<?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=80.72.130.218</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=80.72.130.218"/>
	<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/articles/Spezial:Beitr%C3%A4ge/80.72.130.218"/>
	<updated>2026-04-10T19:46:18Z</updated>
	<subtitle>Benutzerbeiträge</subtitle>
	<generator>MediaWiki 1.39.7</generator>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=FAQ&amp;diff=52624</id>
		<title>FAQ</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=FAQ&amp;diff=52624"/>
		<updated>2010-11-08T12:57:19Z</updated>

		<summary type="html">&lt;p&gt;80.72.130.218: /* Funktionszeigertabellen */&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;c&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;/c&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()===&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 Libary [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;c&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;/c&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;c&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;/c&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;c&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;/c&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.&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;
  &amp;lt;b&amp;gt;%[Modifizierer][Feldbreite][.Präzision]Typ&amp;lt;/b&amp;gt;&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 aber als Hexadezimalzahl&lt;br /&gt;
  &amp;lt;b&amp;gt;X&amp;lt;/b&amp;gt;    ein int wird ausgegeben, die Ausgabe erfolgt aber als Hexadezimalzahl, wobei Grossbuchstaben verwendet werden.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Die &amp;lt;b&amp;gt;Feldbreite&amp;lt;/b&amp;gt; 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).&lt;br /&gt;
&lt;br /&gt;
Der &amp;lt;b&amp;gt;Modifizierer&amp;lt;/b&amp;gt; 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 &amp;lt;b&amp;gt;Präzision&amp;lt;/b&amp;gt; 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;b&amp;gt;&amp;quot;%d&amp;quot;&amp;lt;/b&amp;gt; Ausgabe eines Integer&lt;br /&gt;
* &amp;lt;b&amp;gt;&amp;quot;%5d&amp;quot;&amp;lt;/b&amp;gt; Ausgabe eines Integer in einem Feld mit 5 Zeichen Breite&lt;br /&gt;
* &amp;lt;b&amp;gt;&amp;quot;%05d&amp;quot;&amp;lt;/b&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;b&amp;gt;&amp;quot;%-5d&amp;quot;&amp;lt;/b&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;b&amp;gt;&amp;quot;%6.3f&amp;quot;&amp;lt;/b&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;c&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;/c&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;c&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;/c&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;c&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;/c&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;
* [[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;c&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;/c&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;c&amp;gt;&lt;br /&gt;
double i;&lt;br /&gt;
i = 5 / 8;&lt;br /&gt;
&amp;lt;/c&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;c&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;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Generell implementiert der Compiler eine Operation immer im &#039;höchsten&#039; Datentyp, der in einer Operation vorkommt. 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.&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 Konstante?==&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 Konstante in hexadezimaler bzw. oktaler Schreibweise immer einen unsigned Datentyp haben.&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;c&amp;gt;&lt;br /&gt;
   (long)5&lt;br /&gt;
&amp;lt;/c&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;c&amp;gt;&lt;br /&gt;
    5L&lt;br /&gt;
&amp;lt;/c&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;c&amp;gt;&lt;br /&gt;
    5.0&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
ist immer eine double Zahl. Es sei denn sie hat explizit eien Suffix&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
    5.0F&lt;br /&gt;
&amp;lt;/c&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;
=Aktivieren der Floating Point Version von sprintf beim WinAVR mit AVR-Studio=&lt;br /&gt;
Beim WinAVR/AVR-Studio wird standardmässig eine Version der printf-Bibliothek verwendet, die keine Floating Point Verarbeitung unterstützt. Die meisten Programme benötigen keine Floating Point Unterstützung, sodass hier wertvoller Programmspeicherplatz gespart werden kann.&lt;br /&gt;
&lt;br /&gt;
Benutzt man dann allerdings eine printf Variante für die Ausgabe von Floating Point Zahlen, so erscheint an Stelle der korrekt formatierten Zahl lediglich ein &#039;?&#039;. Dies ist ein Indiz, dass die Floating Point Verarbeitung im Projekt aktiviert werden muss.&lt;br /&gt;
&lt;br /&gt;
Um die Floating Point Verarbeitung zu aktivieren, geht man im AVR-Studio wie folgt vor:&lt;br /&gt;
Menüpunkt: &amp;quot;&amp;lt;b&amp;gt;Project&amp;lt;/b&amp;gt;&amp;quot;/&amp;quot;&amp;lt;b&amp;gt;Configuration Options&amp;lt;/b&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Im sich öffnenden Dialog wird in der linken Navigationsleiste der Eintrag &amp;quot;&amp;lt;b&amp;gt;Libraries&amp;lt;/b&amp;gt;&amp;quot; ausgewählt.&lt;br /&gt;
Unter &#039;&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Available Link Objects&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;&#039; werden alle möglichen Bibliotheken angeboten. Für die Aktivierung der Floating Point Unterstützung sind 2 interessant: &lt;br /&gt;
* &amp;lt;b&amp;gt;libprintf_flt.a&amp;lt;/b&amp;gt;&lt;br /&gt;
* &amp;lt;b&amp;gt;libm.a&amp;lt;/b&amp;gt;&lt;br /&gt;
Beide Bibliotheken werden durch aktivieren und einen Druck auf &amp;quot;&amp;lt;b&amp;gt;Add Library --&amp;gt;&amp;lt;/b&amp;gt;&amp;quot; in die rechte Spalte übernommen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;libc.a&amp;lt;/b&amp;gt; sollte übrigens &amp;lt;u&amp;gt;nicht&amp;lt;/u&amp;gt; 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;
&lt;br /&gt;
[[Bild:AVR_Studio_float1.gif]]&lt;br /&gt;
&lt;br /&gt;
Danach wählt man in der Navigationsleiste den Eintrag &amp;quot;&amp;lt;b&amp;gt;Custom Options&amp;lt;/b&amp;gt;&amp;quot;. Unter &#039;&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Custom Compilation Options&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;&#039; wird &#039;&amp;lt;i&amp;gt;[Linker Options]&amp;lt;/i&amp;gt;&#039; ausgewählt und in das Textfeld rechts/unten wird der Text&lt;br /&gt;
&amp;lt;b&amp;gt;-Wl,-u,vfprintf&amp;lt;/b&amp;gt;&lt;br /&gt;
eingegeben. Ein Druck auf &amp;quot;&amp;lt;b&amp;gt;Add&amp;lt;/b&amp;gt;&amp;quot; befördert die Zeile in das Listenfeld darüber, welches die Kommandos an den Linker enthält.&lt;br /&gt;
&lt;br /&gt;
[[Bild:AVR_Studio_float2.gif]]&lt;br /&gt;
&lt;br /&gt;
Damit ist die Konfiguration abgeschlossen, &amp;quot;&amp;lt;b&amp;gt;OK&amp;lt;/b&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=Wie funktioniert String-Verarbeitung in C?=&lt;br /&gt;
&lt;br /&gt;
In C gibt es, anders als in anderen Programmiersprachen, keinen eigenen String-Datentyp. Als Ersatz dafür werden Character-Arrays benutzt, in denen die einzelnen Character (=Zeichen) gespeichert werden. Allerdings gibt es noch einen Zusatz: Das letzte Zeichen eines Strings ist immer ein &#039;\0&#039;-Zeichen, dass das Ende des Strings markiert. Schlieslich kann ja das Array wesentlich größer sein, als der in ihm gespeicherte String und irgendwie müssen ja diverse Funktionen das tatsächliche Ende eines Strings erkennen können.&lt;br /&gt;
&lt;br /&gt;
Möchte man also die Zeichenkette &amp;quot;Hello World&amp;quot; in einem String speichern, so wird dafür ein Array mit mindestens der Länge 12 benötigt. 11 für die Zeichen die &amp;quot;Hello World&amp;quot; bilden, plus eine zusätzliche Position für das abschliesende &#039;\0&#039;-Zeichen.&lt;br /&gt;
&lt;br /&gt;
Da Strings in char-Arrays gespeichert werden, können selbstverständlich normale Array Operationen dafür benutzt werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
  char Test[12];&lt;br /&gt;
&lt;br /&gt;
  Test[0] = &#039;H&#039;;&lt;br /&gt;
  Test[1] = &#039;e&#039;;&lt;br /&gt;
  Test[2] = &#039;l&#039;;&lt;br /&gt;
  Test[3] = &#039;l&#039;;&lt;br /&gt;
  Test[4] = &#039;o&#039;;&lt;br /&gt;
  Test[5] = &#039; &#039;;&lt;br /&gt;
  Test[6] = &#039;W&#039;;&lt;br /&gt;
  Test[7] = &#039;o&#039;;&lt;br /&gt;
  Test[8] = &#039;r&#039;;&lt;br /&gt;
  Test[9] = &#039;l&#039;;&lt;br /&gt;
  Test[10] = &#039;d&#039;;&lt;br /&gt;
  Test[11] = &#039;\0&#039;;   // das abschliessende \0 nicht vergessen! Sonst ist&lt;br /&gt;
                     // das kein String!&lt;br /&gt;
&lt;br /&gt;
  char Temp[6];&lt;br /&gt;
&lt;br /&gt;
  for( i = 0; i &amp;lt; 6; ++i )&lt;br /&gt;
    Temp[i] = Test[ i + 6 ];&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Hinweis:&#039;&#039;&#039; Das &amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;&#039;&amp;lt;/font&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&#039;&#039;&#039;\0&#039;&#039;&#039;&amp;lt;/font&amp;gt;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;&#039;&amp;lt;/font&amp;gt; ist nichts anderes als eine binäre Null. Diese spezielle Schreibweise soll explizit die Verwendung dieser &#039;&#039;0&#039;&#039; als Stringende - Character &#039;&#039;(char)0&#039;&#039; hervorheben.&lt;br /&gt;
&lt;br /&gt;
Wird im C-Quelltext ein String in der Form &amp;quot;Hello World&amp;quot; geschrieben, also nicht als einzelne Zeichen, so muss man sich um das abschliessende &#039;\0&#039; Zeichen nicht kümmern. Der Compiler ergänzt das stillschweigend von selbst.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Einige Stringfunktionen ==&lt;br /&gt;
Arrays sind in C keine vollwertigen Datentypen, z.&amp;amp;nbsp;B. ist es nicht möglich einem Array in einem Rutsch ein anderes Array zuzuweisen oder 2 Arrays miteinander zu vergleichen. Genau das möchte man aber in der Stringverarbeitung häufig, sodass es dafür Standardfunktionen gibt, die allesamt im Headerfile &amp;quot;string.h&amp;quot; zusammengefasst sind und deren Namen alle mit str... beginnen. Allen diesen Funktionen gemeinsam ist, dass sie sich &amp;lt;font color=FF0000&amp;gt;&amp;lt;b&amp;gt;nicht&amp;lt;/b&amp;gt;&amp;lt;/font&amp;gt; um die korrekte Bereitstellung von Arrays kümmern, sondern davon ausgehen, dass dies vom Programmierer korrekt erledigt wird.&lt;br /&gt;
&lt;br /&gt;
=== strcpy( char* dest, const char* src ) ===&lt;br /&gt;
Kopieren eines Strings von der Speicherfläche auf die src zeigt, zur Speicherfläche, auf die dest zeigt.&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
  char Ziel1[20];&lt;br /&gt;
  char Ziel2[20];&lt;br /&gt;
&lt;br /&gt;
  strcpy( Ziel1, &amp;quot;Hallo Welt&amp;quot; );&lt;br /&gt;
  strcpy( Ziel2, Ziel1 );&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== strcat( char* dest, const char* src ) ===&lt;br /&gt;
Anhängen eines Strings an einen bestehenden String.&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
  char Ziel[20];&lt;br /&gt;
  char Temp[20];&lt;br /&gt;
&lt;br /&gt;
  strcpy( Ziel, &amp;quot;Hallo &amp;quot; );    // Ziel enthält jetzt den String &amp;quot;Hallo &amp;quot;&lt;br /&gt;
  strcat( Ziel, &amp;quot;Welt&amp;quot; );      // Ziel enthält jetzt den String &amp;quot;Hallo Welt&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  strcpy( Temp, &amp;quot; !&amp;quot; );&lt;br /&gt;
  strcat( Ziel, Temp );        // Ziel enthält jetzt den String &amp;quot;Hallo Welt !&amp;quot;&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== strcmp( const char* str1, const char* str2 ) ===&lt;br /&gt;
Vergleichen 2-er Strings. Das Ergebnis ist 0, wenn die beiden Strings identisch sind.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
  char Ziel[20];&lt;br /&gt;
&lt;br /&gt;
  strcpy( Ziel, &amp;quot;Hallo Welt&amp;quot; );  // Ziel enthält jetzt den String &amp;quot;Hallo Welt&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  if( strcmp( Ziel, &amp;quot;Hallo Welt&amp;quot; ) == 0 )&lt;br /&gt;
    printf( &amp;quot;Ziel war &#039;Hallo Welt&#039;\n&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
  if( strcmp( Ziel, &amp;quot;test&amp;quot; ) != 0 )&lt;br /&gt;
    printf( &amp;quot;Ziel war NICHT &#039;test&#039;\n&amp;quot; );&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== strlen( const char* str ) ===&lt;br /&gt;
Die Länge eines Strings feststellen. Die Länge beinhaltet nicht das abschliessende &#039;\0&#039; Zeichen.&lt;br /&gt;
&lt;br /&gt;
Unter &#039;Länge&#039; wird hier die tatsächliche Länge des Strings (also die Anzahl der im String gespeicherten Zeichen) verstanden und nicht die &#039;Länge&#039; des Arrays in dem der String gespeichert ist. Wird der Text &amp;quot;test&amp;quot; in einem char-Array der Größe 20 gespeichert, so lautet das Ergebnis von strlen() 4 und nicht etwa 20&lt;br /&gt;
&lt;br /&gt;
&amp;lt;C&amp;gt;&lt;br /&gt;
  char string[20];&lt;br /&gt;
  strcpy( string, &amp;quot;test&amp;quot; );&lt;br /&gt;
  i = strlen( string );      // i bekommt hier den Wert 4&lt;br /&gt;
&amp;lt;/C&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Beispiele ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;quot;string.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
  char Meldung[14];&lt;br /&gt;
  strcpy( Meldung, &amp;quot;Hello World&amp;quot; );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
Mittels der Definition&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
  char Meldung[14];&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
wird ein Array bereitgestellt, welches maximal 14 Zeichen aufnehmen kann. &amp;lt;b&amp;gt;Hello World&amp;lt;/b&amp;gt; verbraucht für die lesbaren Zeichen 11 Array-Positionen, dazu noch das obligatorische abschliessende &#039;\0&#039; Zeichen, macht in Summe 12 Positionen. Eine Definition von 14 Zeichen ist also mehr als minimal notwendig&lt;br /&gt;
wäre. Das macht aber nichts, da durch das abschliessende &#039;\0&#039; Zeichen immer feststellbar ist, an welcher Stelle der tatsächliche String zu Ende ist. Die restlichen 2 Array-Positionen sind zur Zeit halt einfach unbenutzt.&lt;br /&gt;
&amp;lt;b&amp;gt;strcpy()&amp;lt;/b&amp;gt; kopiert den 2.ten angegebenen String an die Position auf die sein erstes Argument zeigt. Im obigen Beispiel zeigt das 1.te Argument auf den Beginn von &amp;lt;i&amp;gt;Meldung&amp;lt;/i&amp;gt;, also auf das Array. Folgerichtig wird der String &amp;quot;Hello World&amp;quot; in das Array &amp;lt;i&amp;gt;Meldung&amp;lt;/i&amp;gt; umkopiert. Man beachte auch, dass der Compiler den direkt angegebenen String &amp;quot;Hello World&amp;quot; automatisch mit einem &#039;\0&#039; Zeichen ergänzt hat.&lt;br /&gt;
Nach Ausführung der &amp;lt;b&amp;gt;strcpy()&amp;lt;/b&amp;gt; Funktion enthält also &amp;lt;i&amp;gt;Meldung&amp;lt;/i&amp;gt; den Inhalt:&lt;br /&gt;
&lt;br /&gt;
     +---+---+---+---+---+---+---+---+---+---+---+---+---+---+&lt;br /&gt;
     | H | e | l | l | o |   | W | o | r | l | d | \0|   |   |&lt;br /&gt;
     +---+---+---+---+---+---+---+---+---+---+---+---+---+---+&lt;br /&gt;
     &lt;br /&gt;
Möchte man an diesen Text jetzt noch etwas anfügen, z.&amp;amp;nbsp;B. ein &amp;quot;?&amp;quot;, so würde das so aussehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;quot;string.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
  char Meldung[14];&lt;br /&gt;
  strcpy( Meldung, &amp;quot;Hello World&amp;quot; );&lt;br /&gt;
  strcat( Meldung, &amp;quot;?&amp;quot; );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;font color=&amp;quot;FF0000&amp;quot;&amp;gt;&lt;br /&gt;
Man beachte: auch wenn hier scheinbar nur ein einzelnes Zeichen angehängt wird, so handelt es sich doch um einen String. Strings werden in C immer mit einem &amp;quot; eingeleitet und abgeschlossen. Im Gegensatz zu einzelnen Zeichen, die in einfache &#039; eingefasst werden. &amp;quot;?&amp;quot; ist also nicht dasselbe wie &#039;?&#039;! Das&lt;br /&gt;
erste ist ein String (der mit dem obligatorischen &#039;\0&#039; Zeichen insgesamt aus 2 Zeichen besteht), während letzteres ein einzelnes Zeichen darstellt! Die meisten str... Funktionen arbeiten nur mit Strings!&lt;br /&gt;
&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Da &amp;lt;i&amp;gt;Meldung&amp;lt;/i&amp;gt; maximal 14 Zeichen umfassen kann, der Text &amp;quot;Hello World?&amp;quot; aber nur aus 13 Zeichen besteht, funktioniert Obiges auch ohne Probleme. Der Array-Inhalt sieht dann wie folgt aus:&lt;br /&gt;
&lt;br /&gt;
     +---+---+---+---+---+---+---+---+---+---+---+---+---+---+&lt;br /&gt;
     | H | e | l | l | o |   | W | o | r | l | d | ? | \0|   |&lt;br /&gt;
     +---+---+---+---+---+---+---+---+---+---+---+---+---+---+&lt;br /&gt;
&lt;br /&gt;
Ein schwerwiegender Fehler wäre es, wenn der komplette String nach dem &amp;lt;b&amp;gt;strcat()&amp;lt;/b&amp;gt; aus mehr als 14 Zeichen (das &#039;\0&#039;-Zeichen nicht vergessen!) bestehen würde.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;quot;string.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
  char Meldung[14];&lt;br /&gt;
  strcpy( Meldung, &amp;quot;Hello World&amp;quot; );&lt;br /&gt;
  strcat( Meldung, &amp;quot; von mir&amp;quot; );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
würde also das Array überlaufen lassen.&lt;br /&gt;
&lt;br /&gt;
     +---+---+---+---+---+---+---+---+---+---+---+---+---+---+&lt;br /&gt;
     | H | e | l | l | o |   | W | o | r | l | d |   | v | o | n       m   i   r   \0&lt;br /&gt;
     +---+---+---+---+---+---+---+---+---+---+---+---+---+---+&lt;br /&gt;
&lt;br /&gt;
Man sieht sehr schön, daß in diesem Fall die weiteren Zeichen einfach an die Folgepositionen im Speicher geschrieben werden und dadurch ungewollt Speicher verändern, der nicht zu &amp;lt;i&amp;gt;Meldung&amp;lt;/i&amp;gt; gehört. Abhängig von den Details des Programmes können aber an dieser Stelle im Speicher z.&amp;amp;nbsp;B. ganz andere Variablen liegen, die dann verändert werden. &amp;lt;b&amp;gt;strcpy()&amp;lt;/b&amp;gt;, &amp;lt;b&amp;gt;strcat()&amp;lt;/b&amp;gt; oder alle anderen String-Funktionen können den Programmierer gegen diesen Fall nicht schützen! Dazu müssten sie die Größe des Speicherbereichs kennen, was sie nicht tun. Es obliegt einzig und alleine der Sorgfalt des Programmierers, das Programm gegen solche Fälle abzusichern!&lt;br /&gt;
&lt;br /&gt;
Seit einiger Zeit wurde das Sammelsurium der str... Funktionen durch Varianten ergänzt, die sich anschicken dieses Manko zu entschärfen. Diesen Funktionen wird die maximale Anzahl der zu bearbeitenden Zeichen mitgegeben. Mit der Kenntnis der Größe des Zielbereichs und der Länge des bereits darin enthaltenen Strings ist es damit möglich eine Obergrenze auszurechnen, wieviele Zeichen von einer Funktion gefahrlos bearbeitet werden dürfen, ehe der Zielbereich überlaufen würde.&lt;br /&gt;
&lt;br /&gt;
Diese Funktionen heißen grundsätzlich gleich wie die str... Funktionen, nur befindet sich ein kleines &#039;n&#039; im Funktionsnamen. Aus &amp;lt;b&amp;gt;strcpy&amp;lt;/b&amp;gt; wird so &amp;lt;b&amp;gt;strncpy&amp;lt;/b&amp;gt;, aus &amp;lt;b&amp;gt;strcat&amp;lt;/b&amp;gt; wird &amp;lt;b&amp;gt;strncat&amp;lt;/b&amp;gt; usw. Für Details dazu sei auf Literatur oder Web-Recherche verwiesen. Auch wenn einen diese Funktionen gegen die gefürchteten Array-Overflows schützen können, so muß man sich trotzem klarmachen, daß dieser Schutz nur die halbe Miete ist. Denn was soll &amp;lt;b&amp;gt;strncpy&amp;lt;/b&amp;gt; denn tun, wenn der zu kopierende String nicht in das Zielarray passt? &amp;lt;b&amp;gt;strncpy&amp;lt;/b&amp;gt; kopiert soviel wie es kann und gibt dann auf. Aber: Dadurch ist der String aber nicht zur Gänze in den Zielbereich kopiert worden. Programmteile die darauf angewiesen sind, daß der String vollständig kopiert wurde, werden dann nicht mehr oder nicht richtig funktionieren usw. Auch wenn die strn... Funktionen eine gewisse Abhilfe bringen und zumindest den Absturz eines Programmes verhindern können, stellen sie dennoch keine Allheilmittel dar. Um die korrekte Abschätzung der benötigten Arraygrößen kommt man nicht umhin.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;strlen()&amp;lt;/b&amp;gt; liefert die Länge eines Strings. Die Längenangabe beinhaltet dabei nicht das abschliessende &#039;\0&#039; Zeichen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;quot;string.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
  char Meldung[14];&lt;br /&gt;
  int  Len;&lt;br /&gt;
  &lt;br /&gt;
  strcpy( Meldung, &amp;quot;Hello World&amp;quot; );&lt;br /&gt;
  Len = strlen( Meldung );&lt;br /&gt;
  &lt;br /&gt;
  /* Hier enthaelt Len den Wert 11 */&lt;br /&gt;
&lt;br /&gt;
  Len = strlen( &amp;quot;Hallo Welt&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
  /* Hier enthält Len den Wert 10 */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;strcmp()&amp;lt;/b&amp;gt; schlussendlich vergleicht 2 Strings auf Gleichheit. Der Rückgabewert spiegelt dabei die Position des ersten Unterschiedes in den beiden Strings wieder. Folgerichtig sagt ein Wert von 0 daher aus, dass die beiden Strings identisch sind:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#include &amp;quot;string.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
  char Meldung1[14];&lt;br /&gt;
  char Meldung2[14];&lt;br /&gt;
&lt;br /&gt;
  strcpy( Meldung1, &amp;quot;Hello World&amp;quot; );&lt;br /&gt;
  strcpy( Meldung2, &amp;quot;Hallo Welt&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
  if( strcmp( Meldung1, Meldung2 ) == 0 ) {&lt;br /&gt;
    /* die Strings sind identisch */&lt;br /&gt;
  }&lt;br /&gt;
  else {&lt;br /&gt;
    /* die Strings sind nicht identisch */&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  if( strcmp( Meldung2, &amp;quot;Hallo Welt&amp;quot; ) == 0 ) {&lt;br /&gt;
    /* Meldung2 war &amp;quot;Hallo Welt&amp;quot; */&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es gibt noch weitere String-Funktionen, dafür sei aber auf die Verwendung der zum Compiler gehörenden Dokumentation bzw. auf einführende Literatur zum Thema &#039;Programmieren in C&#039; verwiesen.&lt;br /&gt;
&lt;br /&gt;
== wie schreibt man eine Funktion, die einen String liefert? ==&lt;br /&gt;
&lt;br /&gt;
will man eine Funktion schreiben, die einen String liefert, so hat man ein Problem. So gehts nicht:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
  char string[10];&lt;br /&gt;
  c = uart_get_line();&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
char uart_get_line()&lt;br /&gt;
{&lt;br /&gt;
  char  string[10];&lt;br /&gt;
  uint8_t i = 0;&lt;br /&gt;
&lt;br /&gt;
  for( ... )&lt;br /&gt;
  {&lt;br /&gt;
    ...&lt;br /&gt;
    string[i] = ...;&lt;br /&gt;
    ...&lt;br /&gt;
  }&lt;br /&gt;
  string[i] = &#039;\0&#039;;&lt;br /&gt;
  return *string;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Strings sind ja nichts anderes als Zeichen in einem Array und Arrays kann man nicht als Ganzes  in C einfach so zuweisen. Das bedeutet aber auch, dass uart_get_line gar nicht ein Array als solches liefern kann! Daher hat auch der Programmierer versucht, sich mit einem char als Rückgabewert bzw. dem *string im return sich aus der Affäre zu ziehen. Nur: so funktioniert das nicht. uart_get_line würde hier nur ein einziges Zeichen zurückliefern und keinen String!&lt;br /&gt;
&lt;br /&gt;
Eine naheliegende Lösung wäre:&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
// liest eine Zeile (maximal 9 Zeichen) und liefert sie als&lt;br /&gt;
// nullterminierten String zurück:&lt;br /&gt;
char * uart_get_line()&lt;br /&gt;
{&lt;br /&gt;
  char string[10];&lt;br /&gt;
  uint8_t i = 0;&lt;br /&gt;
&lt;br /&gt;
  for( ... )&lt;br /&gt;
  {&lt;br /&gt;
    ...&lt;br /&gt;
    string[i] = ...;&lt;br /&gt;
    ...&lt;br /&gt;
  }&lt;br /&gt;
  string[i] = &#039;\0&#039;;&lt;br /&gt;
  return string;  // nicht *string&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das ist jetzt schon etwas besser, aber immer noch falsch.&lt;br /&gt;
&lt;br /&gt;
Gebessert hat sich ja schon der Rückgabetyp; dazu passt das return&lt;br /&gt;
string statt return *string.&lt;br /&gt;
&lt;br /&gt;
Mit *string würde man ja ein char liefern, und zwar das unterste in&lt;br /&gt;
string, mithin string[0].&lt;br /&gt;
Jetzt will ma ja aber nicht das eine Zeichen liefern, sondern den ganzen&lt;br /&gt;
String. Und das geschieht in C, indem man einen Zeiger auf das erste&lt;br /&gt;
Zeichen nimmt. Das ist string.&lt;br /&gt;
&lt;br /&gt;
Falsch (und zwar richtig falsch!) ist diese Lösung aber aus folgendem Grund:&lt;br /&gt;
string ist eine automatische Variable (alle lokalen Variablen in einer&lt;br /&gt;
Funktion oder in einem Block sind automatisch, wenn nicht static davor&lt;br /&gt;
steht). Eine automatische Variable existiert aber nur, solange der umgebende&lt;br /&gt;
Block (hier die Funktion) abgearbeitet wird.&lt;br /&gt;
Sofort danach kann der Speicherplatz für etwas anderes genutzt werden,&lt;br /&gt;
meist für Parameter einer aufgerufenen Funktion, oder deren lokale&lt;br /&gt;
Variablen, oder Rücksprungadressen, temporäre Zwischenwerte oder was&lt;br /&gt;
auch immer.&lt;br /&gt;
&lt;br /&gt;
Normalerweise ist das in Ordnung, weil man ja auf eine Variable mit&lt;br /&gt;
ihrem Namen nur zugreifen kann, solange man in demselben Block ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
    {&lt;br /&gt;
       int i = 12;&lt;br /&gt;
       i += 12;&lt;br /&gt;
    }&lt;br /&gt;
    printf( &amp;quot;%d&amp;quot;, i ); // geht nicht&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So etwas verhindert der Compiler aus gutem Grund: i ist eine Variable&lt;br /&gt;
in dem Block mit den geschweiften Klammern und existiert nur solange&lt;br /&gt;
der Block abgearbeitet wird.&lt;br /&gt;
Das printf() steht außerhalb, hier lässt der Compiler die Verwendung&lt;br /&gt;
von i nicht mehr zu - die Variable existiert dann auch gar nicht mehr.&lt;br /&gt;
Ändert man das etwas ab, hat man den Compiler überlistet:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
    int* zeiger_auf_i;&lt;br /&gt;
    {&lt;br /&gt;
       int i = 12;&lt;br /&gt;
       i += 12;&lt;br /&gt;
       zeiger_auf_i = &amp;amp;i;&lt;br /&gt;
    }&lt;br /&gt;
    ...&lt;br /&gt;
    printf( &amp;quot;%d&amp;quot;, *zeiger_auf_i );&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jetzt macht man im Prinzp dasselbe wie eben, nur etwas umständlicher.&lt;br /&gt;
In zeiger_auf_i merkt man sich die Adresse von i, und im printf()&lt;br /&gt;
benutzt man die Adresse um auf i zuzugreifen.&lt;br /&gt;
Jetzt verhindert Compiler das nicht. Syntaktisch geht alles mit rechten Dingen zu. Es ist aber noch genauso falsch: wenn das printf() läuft, wird über&lt;br /&gt;
den Zeiger auf i zugegriffen, obwohl i gar nicht mehr existiert&lt;br /&gt;
bzw. möglicherweise schon lange für etwas anderes benutzt wird.&lt;br /&gt;
&lt;br /&gt;
Mit solchen Konstruktionen kann man sich in C schön selbst verarschen,&lt;br /&gt;
wenn man nicht weiß was man tut.&lt;br /&gt;
&lt;br /&gt;
Im Prinzip etwas ähnliches macht man mit dem obigen falschen Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
// liest eine Zeile (maximal ... Zeichen) und liefert sie als&lt;br /&gt;
// nullterminierten String zurück:&lt;br /&gt;
char* uart_get_line()&lt;br /&gt;
{&lt;br /&gt;
  char string[10];&lt;br /&gt;
  uint8_t i = 0;&lt;br /&gt;
&lt;br /&gt;
  for( ... )&lt;br /&gt;
  {&lt;br /&gt;
    ...&lt;br /&gt;
    string[i] = ...;&lt;br /&gt;
    ...&lt;br /&gt;
  }&lt;br /&gt;
  string[i] = &#039;\0&#039;;&lt;br /&gt;
  return string;  // nicht *string&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
   ...&lt;br /&gt;
   char* meinezeile;&lt;br /&gt;
   meinezeile = uart_get_line();&lt;br /&gt;
   printf( &amp;quot;gelesen: %s&amp;quot;, meinezeile );&lt;br /&gt;
   ...&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(Es soll jetzt mal egal sein, daß es ein printf() in dieser Form gar&lt;br /&gt;
nicht auf einem AVR gibt; es geht nur darum, den String irgendwie zu&lt;br /&gt;
verwenden.)&lt;br /&gt;
&lt;br /&gt;
Was passiert bei diesem Beispiel?&lt;br /&gt;
in uart_get_line() gibt es eine lokale (automatische) Variable string;&lt;br /&gt;
das ist ein Feld mit 10 Zeichen.&lt;br /&gt;
Beim Rücksprung wird die Adresse des ersten Elements zurückgegeben und&lt;br /&gt;
beim Aufrufer in meinezeile gespeichert. meinezeile ist also ein Zeiger auf das erste Zeichen von string. Der springede Punkt ist: Die Variable string existiert nach Verlasse4n der Funktion gar nicht mehr! Man hat daher einen Pointer, der auf etwas Ungültiges zeigt. Da muss nicht unbedingt heißen, dass es nicht so aussehen kann, als ob so etwas funktionieren würde. Solange der Speicherplatz der ehemaligen Variablen string nicht für andere Zwecke gebraucht wurde, kann man unter Umständen sogar über den Pointer an die korrekten Zeichen kommen. Der physikalische Speicher verschwindet ja nicht irgendwie magisch. Der ist schon noch da. Nur haben wir keine Garantie, dass auch das drinnen steht, was unserer Meinung nach drinnen stehen sollte, denn dieser Speicher ist ja nicht mehr für die ausschliessliche Verwendung durch die Variable string reserviert.&lt;br /&gt;
&lt;br /&gt;
Bei soetwas muß man in C ziemlich nervös werden!&lt;br /&gt;
So ist es jedenfalls Murks.&lt;br /&gt;
&lt;br /&gt;
Es gibt mehrere Möglichkeiten, das zu verbessern,&lt;br /&gt;
Leider sind sie alle nicht richtig schick, jede Variante ist irgendwie&lt;br /&gt;
etwas doof.&lt;br /&gt;
&lt;br /&gt;
=== Erste Möglichkeit: Den String static machen ===&lt;br /&gt;
Dann ist es keine automatische Variable mehr, die daher auch nicht beim Verlassen der Funktion zerstört wird:&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
// liest eine Zeile (maximal ... Zeichen) und liefert sie als&lt;br /&gt;
// nullterminierten String zurück:&lt;br /&gt;
char* uart_get_line()&lt;br /&gt;
{&lt;br /&gt;
  static char string[10];&lt;br /&gt;
  uint8_t i = 0;&lt;br /&gt;
&lt;br /&gt;
  for( ... )&lt;br /&gt;
  {&lt;br /&gt;
    ...&lt;br /&gt;
    string[i] = ...;&lt;br /&gt;
    ...&lt;br /&gt;
  }&lt;br /&gt;
  string[i] = &#039;\0&#039;;&lt;br /&gt;
  return string;  // nicht *string&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
   ...&lt;br /&gt;
   char* meinezeile;&lt;br /&gt;
   meinezeile = uart_get_line();&lt;br /&gt;
   printf( &amp;quot;gelesen: %s&amp;quot;, meinezeile );&lt;br /&gt;
   ...&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Damit klappt es auf einmal wundersamerweise.&lt;br /&gt;
Eine static-Variable wird nicht immer neu angelegt und wieder&lt;br /&gt;
wegegworfen, sondern existiert einmal von Programmstart bis&lt;br /&gt;
Programmende.&lt;br /&gt;
&lt;br /&gt;
Aber wo ist dabei der Haken?&lt;br /&gt;
Daß sie eben nur einmal existiert.&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
   char* meinezeile1;&lt;br /&gt;
   char* meinezeile2;&lt;br /&gt;
&lt;br /&gt;
   meinezeile1 = uart_get_line();&lt;br /&gt;
   printf( &amp;quot;gelesen1: %s&amp;quot;, meinezeile1 ); // gibte erste Zeile aus&lt;br /&gt;
   meinezeile2 = uart_get_line();&lt;br /&gt;
   printf( &amp;quot;gelesen2: %s&amp;quot;, meinezeile2 ); // gibte zweite Zeile aus&lt;br /&gt;
&lt;br /&gt;
   printf( &amp;quot;gelesen1: %s&amp;quot;, meinezeile1 ); // gibte zweite Zeile aus (!)&lt;br /&gt;
   printf( &amp;quot;gelesen2: %s&amp;quot;, meinezeile2 ); // gibte zweite Zeile aus&lt;br /&gt;
   ...&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel sieht es erst vernünftig aus: mit meinezeile1 wird&lt;br /&gt;
die erste gelesene Zeile ausgegeben, mit meinezeile2 dann die zweite.&lt;br /&gt;
Mit der folgenden Ausgabe wird sowohl für meinezeile1 als auch für&lt;br /&gt;
meinezeile2 nur noch die letzte gelesene Zeile (also die zweite)&lt;br /&gt;
ausgegeben, weil in der static-Variable string ja mit der zweiten&lt;br /&gt;
Zeile die erste überschrieben wurde und sowohl meinezeile1 als auch meinezeile2 ja Zeiger auf dieses eine Array sind.&lt;br /&gt;
&lt;br /&gt;
Das wird der Aufrufer so wahrscheinlich nicht erwarten; das ist also&lt;br /&gt;
doch etwas problematisch.&lt;br /&gt;
Richtig krank werden static-Variablen bei Programmen, die mit mehreren&lt;br /&gt;
Threads arbeiten, ebenso wie bei rekursiven Funktionsaufrufen.&lt;br /&gt;
Leider sind mehrere Funktionen der Standard-Lib von C mit statischen&lt;br /&gt;
Variablen gebaut und deshalb nicht benutzbar in&lt;br /&gt;
multitasking-Programmen (strtok() z.B. fällt auf die Klappe).&lt;br /&gt;
&lt;br /&gt;
=== Zweite Möglichkeit: dynamische Allokierung ===&lt;br /&gt;
Eine andere Lösung wäre: in der Funktion wird für den gelesenen String&lt;br /&gt;
Speicher allokiert und der Zeiger darauf zurückgegeben:&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
// liest eine Zeile (maximal ... Zeichen) und liefert sie als&lt;br /&gt;
// nullterminierten String zurück:&lt;br /&gt;
char * uart_get_line()&lt;br /&gt;
{&lt;br /&gt;
  uint8_t i = 0;&lt;br /&gt;
&lt;br /&gt;
  char* string = malloc( genugzeichen.... );&lt;br /&gt;
  for( ... )&lt;br /&gt;
  {&lt;br /&gt;
    ...&lt;br /&gt;
    string[i] = ...;&lt;br /&gt;
    ...&lt;br /&gt;
  }&lt;br /&gt;
  string[i] = &#039;\0&#039;;&lt;br /&gt;
  return string;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
   ...&lt;br /&gt;
   char* meinezeile;&lt;br /&gt;
   meinezeile = uart_get_line();&lt;br /&gt;
   printf( &amp;quot;gelesen: %s&amp;quot;, meinezeile );&lt;br /&gt;
   free( meinezeile ); // Speicher nach letzter Benutzung freigeben&lt;br /&gt;
   ...&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
Das würde jetzt auch bei Multitasking funktionieren ebenso wie bei&lt;br /&gt;
Rekursion.&lt;br /&gt;
&lt;br /&gt;
Und wo ist hier der Haken?&lt;br /&gt;
In der Funktion wird Speicher allokiert, und erst der Aufrufer kann den&lt;br /&gt;
Speicher freigeben - wenn er es nicht vergisst.&lt;br /&gt;
&lt;br /&gt;
Leider wird es mehr oder weniger häufig vergessen, weswegen es als&lt;br /&gt;
höchst unelegant gilt, in einer Funktion Speicher zu allokieren, der&lt;br /&gt;
vom Aufrufer wieder freigegeben werden muß.&lt;br /&gt;
&lt;br /&gt;
Auf einem Controller wird man diese Lösung auch nicht gerne sehen,&lt;br /&gt;
weil es da wegen des knappen Speichers selten ratsam ist, dynamische&lt;br /&gt;
Speicherverwaltung mit malloc() zu nutzen.&lt;br /&gt;
Ich hatte hier ja auch die Fehlerbehandlung unterschlagen: Was soll&lt;br /&gt;
passieren, wenn gar kein Speicher allokiert werden kann? Auf einem&lt;br /&gt;
Controller kann man ja nicht einfach eine kurze Meldung ausgeben und&lt;br /&gt;
das Programm beenden. Ein Absturz wird auch nicht gern gesehen und&lt;br /&gt;
nicht so leicht akzeptiert wie unter Windows.&lt;br /&gt;
&lt;br /&gt;
=== Dritte Möglichkeit: Allokierung durch den Aufrufer ===&lt;br /&gt;
Der Aufrufer selbst beschafft den Platz, übergibt&lt;br /&gt;
ihn und die Funktion schreibt nur rein:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
// liest eine Zeile (maximal ... Zeichen) und liefert sie als&lt;br /&gt;
// nullterminierten String zurück:&lt;br /&gt;
char * uart_get_line( char* string, size_t l_puffer )&lt;br /&gt;
{&lt;br /&gt;
  uint8_t i = 0;&lt;br /&gt;
&lt;br /&gt;
  for( ... &amp;amp;&amp;amp; i&amp;lt;l_puffer-1 )&lt;br /&gt;
  {&lt;br /&gt;
    ...&lt;br /&gt;
    string[i] = ...;&lt;br /&gt;
    ...&lt;br /&gt;
  }&lt;br /&gt;
  string[i] = &#039;\0&#039;;&lt;br /&gt;
  return string;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
   ...&lt;br /&gt;
   char meinezeile[10];&lt;br /&gt;
   uart_get_line( meinezeile, 10 );&lt;br /&gt;
   printf( &amp;quot;gelesen: %s&amp;quot;, meinezeile );&lt;br /&gt;
   ...&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Weil die Funktion nicht feststellen kann, wie groß der Puffer ist, muß&lt;br /&gt;
der Aufrufer auch gleich die Länge übergeben.&lt;br /&gt;
&lt;br /&gt;
Das hat nebenbei den Vorteil, daß man in der Funktion nicht mehr&lt;br /&gt;
spekulieren muß, wieviel Platz nötig ist (wie kommt man gerade auf die 10?&lt;br /&gt;
Woher soll man das in der Funktion wissen?). Die Funktion kann also je nach Situation mal mit einem großen oder mal mit einem kleinen Puffer aufgerufen werden.&lt;br /&gt;
Dafür hat man aber wieder das umgekehrte Problem: Was ist, wenn der Aufrufer nicht weiß oder wissen kann, wie groß ein String werden kann. Besonders problematisch ist das zb. bei Benutzereingaben oder in Situationen in denen der String durch Datenübertragung entsteht. Niemand kann zuverlässig vorhersagen, wieviele Zeichen ein Benutzer eingeben wird. Nur: Wie soll der Aufrufer einer entsprechenden Funktion dies dann wissen?&lt;br /&gt;
&lt;br /&gt;
Nachteil dieser Lösung ist ausserdem, daß der Aufruf etwas umständlich ist (2&lt;br /&gt;
Parameter mehr).&lt;br /&gt;
&lt;br /&gt;
=Funktionszeiger=&lt;br /&gt;
Um Menüs oder ähnliche Dinge aufzubauen ist es oft praktisch ein Array von Funktionszeigern zu definieren. Der Aufruf einer Funktion kann dann indirekt über eine Variable erfolgen, wobei die Variable die Adresse der aufzurufenden Funktion enthält.&lt;br /&gt;
&lt;br /&gt;
Um mit Funktionszeigern zu arbeiten ist es in der Praxis sinnvoll sich einen &amp;lt;b&amp;gt;typedef&amp;lt;/b&amp;gt; für den Typ des Funktionszeigers zu definieren. Ein &amp;lt;b&amp;gt;typedef&amp;lt;/b&amp;gt; definiert einen neuen (kürzeren) Namen für einen Datentyp. Und wie wir sehen werden, ist der Datentyp eines Funktionszeigers in der Schreibweise ganz schön umfangreich.&lt;br /&gt;
&lt;br /&gt;
==typedef==&lt;br /&gt;
Einen &amp;lt;b&amp;gt;typedef&amp;lt;/b&amp;gt; zu definieren ist eigentlich ganz einfach: Man schreibt die Deklaration so, als ob man eine Variable definieren würde. Vor das ganze Konstrukt kommt das Schlüsselwort &amp;lt;b&amp;gt;typedef&amp;lt;/b&amp;gt;. Es bewirkt, dass der Name an der Position des Variablennamens zum Namen für den neuen Datentyp wird, der dann in weiterer Folge wie jeder andere Datentyp benutzt werden kann.&lt;br /&gt;
&lt;br /&gt;
Wir wollen einen Funktionszeiger auf eine Funktion definieren, die keine Argumente entgegen nimmt und auch nichts liefert. Also Funktionen nach&lt;br /&gt;
dem Muster:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
void foo( void )&lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ein entsprechender &amp;lt;b&amp;gt;typedef&amp;lt;/b&amp;gt; würde zB so aussehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
typedef void (*VoidFnct)( void );&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das vereinbart einen neuen Datentyp &amp;lt;b&amp;gt;VoidFnct&amp;lt;/b&amp;gt;. Dieser ist ein Funktionszeiger auf Funktionen, die keine Argumente nehmen und auch nichts zurückliefern.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
typedef int (*IntFnct)( void );&lt;br /&gt;
typedef int (*IntFnct2)( int );&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;IntFnct&amp;lt;/b&amp;gt; ist ein Zeiger auf eine Funktion, die keine Argumente nimmt aber einen &amp;lt;b&amp;gt;int&amp;lt;/b&amp;gt; zurückliefert. &amp;lt;b&amp;gt;IntFnct2&amp;lt;/b&amp;gt; hingegen ist ein Zeiger auf eine Funktion, die einen &amp;lt;b&amp;gt;int&amp;lt;/b&amp;gt; als Argument nimmt und einen &amp;lt;b&amp;gt;int&amp;lt;/b&amp;gt; zurückliefert. Andere Argumenttypen bzw. Rückgabetypen folgen dem gleichen Muster. Wichtig ist, dass sowohl Argumenttypen als auch Rückgabetypen Teil der Signatur eines Funktionszeigers ist. Es ist also nicht möglich einen Funktionszeigertyp zu vereinbaren, der auf beliebige Funktionen mit beliebigen Argumenttypen bzw. Rückgabetypen verweist. Hier muss man ev. auf einen cast ausweichen. Generell ist das aber meist keine gute Idee.&lt;br /&gt;
&lt;br /&gt;
Die Bildung des Datentyps ist im Grunde eigentlich sehr einfach: Man nimmt in Gedanken den Funktionskopf her.&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
double CelsiusToFahrenheit( double Celsius )&lt;br /&gt;
{&lt;br /&gt;
  ...&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
Dann werden in der Argumentliste alle Argumentnamen entfernt&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
double CelsiusToFahrenheit( double )&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
Der Funktionsname durch den Namen des Datentyps getauscht&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
double CallbackFnct( double )&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
Vor den Datentypnamen kommt ein * (wie bei allen Zeigerdefinitionen) und rund um dieses Gebilde kommen Klammern (die den * an den Datentypnamen binden und nicht an den Datentyp des Returnwertes)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
double (*CallbackFnct)( double )&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
und fertig ist der Datentyp einer Funktion die einen double als Argument annimmt und einen double als Returnwert liefert. Davor noch der typedef und das abschliessende ; und wir haben einen neuen Datentyp namens CallbackFnct, der einen Funktionszeiger auf Funktionen mit genau dieser Signatur darstellt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
typedef double (*CallbackFnct)( double );&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Funktionszeigertabellen==&lt;br /&gt;
Mit einem &amp;lt;b&amp;gt;typedef&amp;lt;/b&amp;gt; ist es nun ein leichtes ein Array von Funktionszeigern zu vereinbaren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
typedef void (*VoidFnct)( void );&lt;br /&gt;
&lt;br /&gt;
VoidFnct MeineFunktionen[5];&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Im RAM===&lt;br /&gt;
Dies vereinbart &amp;lt;i&amp;gt;MeineFunktionen&amp;lt;/i&amp;gt; als ein Array von Funktionszeigern, wobei jeder Funktionszeiger auf eine Funktion vom Typ void-void zeigt. Diese Tabelle liegt im RAM ab. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
typedef void (*VoidFnct)( void );&lt;br /&gt;
&lt;br /&gt;
void Funct1()&lt;br /&gt;
{&lt;br /&gt;
  printf( &amp;quot;Dies ist Funktion 1\n&amp;quot; );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Funct2()&lt;br /&gt;
{&lt;br /&gt;
  printf( &amp;quot;Dies ist Funktion 2\n&amp;quot; );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
VoidFnct MeineFunktionen[] = { Funct1, Funct2 };&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
  //&lt;br /&gt;
  // ruft die Funktion auf, deren Adresse in MeineFunktionen[0]&lt;br /&gt;
  // steht. In diesem Fall wäre das Funct1()&lt;br /&gt;
  //&lt;br /&gt;
  MeineFunktionen[0]();&lt;br /&gt;
&lt;br /&gt;
  //&lt;br /&gt;
  // und jetzt die MeineFunktionen[1]&lt;br /&gt;
  //&lt;br /&gt;
  MeineFunktionen[1]();&lt;br /&gt;
&lt;br /&gt;
  //&lt;br /&gt;
  // jetzt wird MeineFunktionen[0] umgeleitet auf Funct2()&lt;br /&gt;
  // Achtung: Auf der rechten Seite wird kein () angegeben.&lt;br /&gt;
  // Ansonsten würde ja die Funktione Funct2 aufgerufen. Wir&lt;br /&gt;
  // wollen aber nur ihre Speicheradresse haben! Daher unterbleibt&lt;br /&gt;
  // das ()&lt;br /&gt;
  //&lt;br /&gt;
  MeineFunktionen[0] = Funct2;&lt;br /&gt;
&lt;br /&gt;
  //&lt;br /&gt;
  // welche Funktion wird jetzt aufgerufen?&lt;br /&gt;
  //&lt;br /&gt;
  MeineFunktionen[0]();&lt;br /&gt;
  // Richtig: Die Funktion, deren Adresse in MeineFunktionen[0]&lt;br /&gt;
  //          steht. Und das ist jetzt Funct2.&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Im Flash===&lt;br /&gt;
Steigt die Anzahl der Funktionen innerhalb der Tabelle stark an und soll deren Inhalt nicht veränderbar sein, kann die sie in den FLASH verlegt werden. Das spart die entsprechenden RAM Ressourcen. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
// &lt;br /&gt;
// stellt Zugriffsfunktionen für FLASH zur Verfügung&lt;br /&gt;
// &lt;br /&gt;
#include &amp;lt;avr/pgmspace.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
typedef void (*VoidFnct)( void );&lt;br /&gt;
&lt;br /&gt;
void Funct1()&lt;br /&gt;
{&lt;br /&gt;
  printf( &amp;quot;Dies ist Funktion 1\n&amp;quot; );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Funct2()&lt;br /&gt;
{&lt;br /&gt;
  printf( &amp;quot;Dies ist Funktion 2\n&amp;quot; );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// legt die Tabelle im FLASH ab&lt;br /&gt;
const VoidFnct MeineFunktionen[] __attribute__ ((progmem)) = { Funct1, Funct2 };&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
  //&lt;br /&gt;
  // legt eine Variable an die mit der Funktionsadresse aus &lt;br /&gt;
  // der Tabelle (die im Flash abliegt) gefüllt wird. &lt;br /&gt;
  //&lt;br /&gt;
  VoidFnct MeineFunktion = 0u;&lt;br /&gt;
&lt;br /&gt;
  //&lt;br /&gt;
  // Lädt die Adresse der Funktion die an MeineFunktionen[0]&lt;br /&gt;
  // steht&lt;br /&gt;
  //&lt;br /&gt;
  MeineFunktion = (VoidFnct)(pgm_read_word(&amp;amp;(MeineFunktionen[0u])));&lt;br /&gt;
&lt;br /&gt;
  //&lt;br /&gt;
  // ruft MeineFunktion auf, welche nun auf die Adresse von &lt;br /&gt;
  // MeineFunktionen[0] zeigt. In diesem Fall wäre das Funct1()&lt;br /&gt;
  //&lt;br /&gt;
  MeineFunktion();&lt;br /&gt;
&lt;br /&gt;
  //&lt;br /&gt;
  // und jetzt die an MeineFunktionen[1], also Funct2()&lt;br /&gt;
  //&lt;br /&gt;
  MeineFunktion = (VoidFnct)(pgm_read_word(&amp;amp;(MeineFunktionen[1u])));&lt;br /&gt;
  MeineFunktion();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Menüs mit Funktionszeigern==&lt;br /&gt;
Besonders bei Menüs ist es oft hilfreich, sich eine Struktur bestehend&lt;br /&gt;
aus dem Menütext und der aufzurufenden Funktion zu definieren. Dazu kann man sich dann auch gleich noch irgendwelche Argumente mit in die Struktur mit aufnehmen, die beim Funktionsaufruf an die Funktion übergeben werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
typedef void (*MenuFnct)( int);&lt;br /&gt;
&lt;br /&gt;
struct MenuEntry {&lt;br /&gt;
  char     Text[20];&lt;br /&gt;
  MenuFnct Function;&lt;br /&gt;
  int      ArgumentToFunction;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ein Menü ist dann einfach ein Array aus derartigen Strukturelementen&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void HandleEdit( int arg )&lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void HandleCopy( int arg )&lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void HandlePaste( int arg )&lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
struct MenuEntry MainMenu[] = {&lt;br /&gt;
 { &amp;quot;Edit&amp;quot;,  HandleEdit,  23 },   // Der Funktion HandleEdit soll beim Aufruf 23 mitgegeben werden&lt;br /&gt;
 { &amp;quot;Copy&amp;quot;,  HandleCopy,   0 },&lt;br /&gt;
 { &amp;quot;Paste&amp;quot;, HandlePaste,  0 }&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
#define ARRAY_SIZE(X) ( sizeof(X) / sizeof(*(X)) )&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void DoMenu( int NrEntries, struct MenuEntry Menu[] )&lt;br /&gt;
{&lt;br /&gt;
  int i;&lt;br /&gt;
  int Auswahl;&lt;br /&gt;
  &lt;br /&gt;
  do {&lt;br /&gt;
    //&lt;br /&gt;
    // Das Menue anzeigen. Für jeden Menuepunkt noch eine Zahl&lt;br /&gt;
    // davor stellen, damit der Benutzer auch was zum Eingeben hat&lt;br /&gt;
    //&lt;br /&gt;
    for( i = 0; i &amp;lt; NrEntries; ++i )&lt;br /&gt;
      printf( &amp;quot;%d) %s\n&amp;quot;, i + 1, Menu[i].Text ); &lt;br /&gt;
&lt;br /&gt;
    printf( &amp;quot;9) Exit\n\n&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
    // &lt;br /&gt;
    // Jetzt die Benutzereingabe abwarten ...&lt;br /&gt;
    //&lt;br /&gt;
    printf( &amp;quot;Ihre Eingabe: &amp;quot; );&lt;br /&gt;
    scanf( &amp;quot;%d&amp;quot;, &amp;amp;Auswahl );&lt;br /&gt;
&lt;br /&gt;
    //&lt;br /&gt;
    // ... und auswerten&lt;br /&gt;
    //&lt;br /&gt;
    if( Auswahl == 9 )&lt;br /&gt;
      return;&lt;br /&gt;
&lt;br /&gt;
    Auswahl = Auswahl - 1;&lt;br /&gt;
    if( Auswahl &amp;lt; 0 || Auswahl &amp;gt; NrEntries )&lt;br /&gt;
      printf( &amp;quot;Ungültige Eingabe\n&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
    else&lt;br /&gt;
      //&lt;br /&gt;
      // Die Eingabe war gültig. Zugehörige Funktion aufrufen und der Funktion&lt;br /&gt;
      // den in der Menüdefinition vermerkten Wert mitgeben&lt;br /&gt;
      //&lt;br /&gt;
      Menu[Auswahl].Function( Menu[Auswahl].ArgumentToFunction );&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
  // Das Menü arbeiten lassen.&lt;br /&gt;
  // Die Funktion DoMenu ruft selbsttätig die zu den jeweiligen&lt;br /&gt;
  // Menüpunkten gehörenden Funktionen auf. DoMenu kommt erst&lt;br /&gt;
  // dann wieder zurück, wenn der Benutzer den Menüpunkt&lt;br /&gt;
  // 9) Exit&lt;br /&gt;
  // ausgewählt hat.&lt;br /&gt;
&lt;br /&gt;
  DoMenu( ARRAY_SIZE( MainMenu ), MainMenu );&lt;br /&gt;
&lt;br /&gt;
  while( 1 )&lt;br /&gt;
    ;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Auf einem Mikrocontroller wird man natürlich die Ein/Ausgabe nicht über &amp;lt;b&amp;gt;printf&amp;lt;/b&amp;gt;/&amp;lt;b&amp;gt;scanf&amp;lt;/b&amp;gt; abwickeln. Hier geht es aber um das Prinzip der Funktionszeiger und wie man mit ihnen arbeitet, daher wurde die allereinfachste Art der Benutzerinteraktion gewählt. Gegebenenfalls muss &amp;lt;b&amp;gt;printf&amp;lt;/b&amp;gt; und &amp;lt;b&amp;gt;scanf&amp;lt;/b&amp;gt; durch die Möglichkeiten auf dem konkreten System ersetzt werden. Auch ist die Art und Weise wie das Menü präsentiert bzw. die Benutzereingabe ausgewertet wird, nicht der Weisheit letzter Schluss. Anstatt den Benutzer Zahlen eingeben zu lassen, könnte man auch einen Auswahl-Balken vom Benutzer mit 2 Tasten über die Menüeinträge bewegen lassen. Oder einen Drehencoder nehmen, ...&lt;br /&gt;
&lt;br /&gt;
=Ich hab da mehrere *.c und *.h Dateien. Was mache ich damit?=&lt;br /&gt;
Zunächst ist es wichtig, sich zu vergegenwärtigen wie denn der C Compiler/Linker überhaupt arbeitet. Ein komplettes Programmier-Projekt kann und wird im Normalfall aus mehreren Source Code Dateien 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;
* zunächst werden alle Einzelteile (jede *.c Datei) für sich &#039;&#039;compiliert&#039;&#039;. Dabei ensteht für jede *.c Datei eine sog. Object-Datei in der bereits der Maschinencode für die im *.c programmierten Funktionen enthalten ist&lt;br /&gt;
* danach werden die einzelnen Object-Dateien zusammen mit zusätzlichen Bibliotheken zum fertigen Programm &#039;&#039;gelinkt&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Angenommen das komplette Projekt besteht aus 2 Dateien&lt;br /&gt;
&lt;br /&gt;
Datei: &amp;lt;b&amp;gt;main.c&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
int twice(int i);&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
  twice( 5 );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Datei: &amp;lt;b&amp;gt;func.c&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;c&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;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
dann werden &amp;lt;b&amp;gt;main.c&amp;lt;/b&amp;gt; und &amp;lt;b&amp;gt;func.c&amp;lt;/b&amp;gt; &amp;lt;i&amp;gt;unabhängig&amp;lt;/i&amp;gt; voneinander compiliert. Als Ergebnis erhält man die Dateien &amp;lt;b&amp;gt;main.o&amp;lt;/b&amp;gt; und &amp;lt;b&amp;gt;func.o&amp;lt;/b&amp;gt; die den besagten Object-Code enthalten. Erst diese beiden Zwischenergebnisse werden dann zusammen mit eventuellen Bibliotheken zum fertigen Programm gebunden (gelinkt), das dann ausgeführt werden kann.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        +---------+                         +----------+&lt;br /&gt;
        | main.c  |                         | func.c   |&lt;br /&gt;
        +---------+                         +----------+&lt;br /&gt;
             |                                   |&lt;br /&gt;
             |                                   |&lt;br /&gt;
             v                                   v&lt;br /&gt;
         Compiler                            Compiler&lt;br /&gt;
             |                                   |&lt;br /&gt;
             |                                   |&lt;br /&gt;
             v                                   v&lt;br /&gt;
        +---------+                         +----------+&lt;br /&gt;
        | main.o  |                         | func.o   |&lt;br /&gt;
        +---------+                         +----------+&lt;br /&gt;
             |                                   |&lt;br /&gt;
             +-----------+   +-------------------+&lt;br /&gt;
                         |   |&lt;br /&gt;
                         v   v&lt;br /&gt;
                         Linker  &amp;lt;------ zus. Bibliotheken&lt;br /&gt;
                           |&lt;br /&gt;
                           v&lt;br /&gt;
                      +----------+&lt;br /&gt;
                      | fertiges |&lt;br /&gt;
                      | Programm |&lt;br /&gt;
                      +----------+&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 ganz einfach in das Projekt mit aufzunehmen. Daduch 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;
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;
Die zusätzliche *.c Datei wird in die SRC Zeile im makefile eingetragen.&lt;br /&gt;
==AVR-Studio==&lt;br /&gt;
Hier ist es besonders einfach eine Datei in das Projekt mit aufzunehmen. Dazu wird im Projektbaum einfach 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 dieses File bei der Projekterzeugung, compiliert es und sorgt dafür, daß es zum fertigen Programm dazugelinkt wird.&lt;br /&gt;
&lt;br /&gt;
=Globale Variablen über mehrere Dateien=&lt;br /&gt;
Ein häufige 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 &amp;lt;b&amp;gt;Definition&amp;lt;/b&amp;gt; und &amp;lt;b&amp;gt;Deklaration&amp;lt;/b&amp;gt; unterscheiden. Worin besteht der Unterschied?&lt;br /&gt;
* &amp;lt;b&amp;gt;Definition&amp;lt;/b&amp;gt;: 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;
* &amp;lt;b&amp;gt;Deklaration&amp;lt;/b&amp;gt;: Mit einer Deklaration teilt man dem Compiler lediglich mit, dass eine Variable existiert. An dieser Stelle soll der Compiler also keinen Speicherplatz reservieren (das muß an anderer Stelle geschehen sein), 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 noch Speicher für diese Variable bereitgestellt wird.&lt;br /&gt;
&lt;br /&gt;
Warum ist diese Unterscheidung jetzt wichtig?&lt;br /&gt;
&lt;br /&gt;
Weil es in C die sog. &amp;lt;b&amp;gt;One Definition Rule&amp;lt;/b&amp;gt; oder kurz &amp;lt;b&amp;gt;ODR&amp;lt;/b&amp;gt; gibt. Sie besagt, dass in einem vollständigem 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;C&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;/C&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;b&amp;gt;extern&amp;lt;/b&amp;gt; vorangestellt.&lt;br /&gt;
* Es kann keine Initialisierung geben. Sobald eine Initialisierung vorhanden ist, wird das Schlüsselwort &amp;lt;b&amp;gt;extern&amp;lt;/b&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;C&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 keine Deklaration!&lt;br /&gt;
&amp;lt;/C&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 Datei gemacht, die auch die main() Funktion enthält. 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;C&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;/C&amp;gt;&lt;br /&gt;
&lt;br /&gt;
helpers.c&lt;br /&gt;
&amp;lt;C&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;/C&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;C&amp;gt;&lt;br /&gt;
extern int Anzahl;&lt;br /&gt;
&amp;lt;/C&amp;gt;&lt;br /&gt;
&lt;br /&gt;
main.c&lt;br /&gt;
&amp;lt;C&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;/C&amp;gt;&lt;br /&gt;
&lt;br /&gt;
foo.c&lt;br /&gt;
&amp;lt;C&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;/C&amp;gt;&lt;br /&gt;
&lt;br /&gt;
bar.c&lt;br /&gt;
&amp;lt;C&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;/C&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;C&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;/C&amp;gt;&lt;br /&gt;
&lt;br /&gt;
main.c&lt;br /&gt;
&amp;lt;C&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;/C&amp;gt;&lt;br /&gt;
&lt;br /&gt;
foo.c&lt;br /&gt;
&amp;lt;C&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;/C&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;C&amp;gt;&lt;br /&gt;
EXTERN int Anzahl;&lt;br /&gt;
&amp;lt;/C&amp;gt;&lt;br /&gt;
vom Präprozessor zu&lt;br /&gt;
&amp;lt;C&amp;gt;&lt;br /&gt;
extern int Anzahl;&lt;br /&gt;
&amp;lt;/C&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;C&amp;gt;&lt;br /&gt;
#define EXTERN&lt;br /&gt;
#include &amp;quot;Global.h&amp;quot;&lt;br /&gt;
&amp;lt;/C&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;C&amp;gt;&lt;br /&gt;
EXTERN int Anzahl;&lt;br /&gt;
&amp;lt;/C&amp;gt;&lt;br /&gt;
wird daher vom Präprozessor zu&lt;br /&gt;
&amp;lt;C&amp;gt;&lt;br /&gt;
int Anzahl;&lt;br /&gt;
&amp;lt;/C&amp;gt;&lt;br /&gt;
erweitert, genau wie es benötigt wird.&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;
[[Kategorie:Grundlagen]]&lt;br /&gt;
[[Kategorie:C]]&lt;/div&gt;</summary>
		<author><name>80.72.130.218</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Zeitgesteuerte_Pflanzenbew%C3%A4sserung&amp;diff=47453</id>
		<title>Zeitgesteuerte Pflanzenbewässerung</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Zeitgesteuerte_Pflanzenbew%C3%A4sserung&amp;diff=47453"/>
		<updated>2010-05-14T09:34:35Z</updated>

		<summary type="html">&lt;p&gt;80.72.130.218: /* Downloads */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;von Philipp Kälin [[Benutzer:philippk]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Einleitung =&lt;br /&gt;
Die zeitgesteuerte Bewässerungsanlage ist für alle geeignet, die zu faul sind um Pflanzen selber zu giessen oder es immer wieder mal vergessen. Ziel des Projektes ist einen einfachen Aufbau zu haben, der per PC konfigurierbar und Batteriebetrieben ist.&lt;br /&gt;
Ein Taster ist vorhanden um die Kommunikation mit dem PC zu aktivieren. Ist die Kommunikation aktiv leuchtet eine LED konstant. Im normalbetrieb ist die LED aus und fängt an zu blinken, wenn die Spannung der Batterie unter einen bestimmten Wert fällt.&lt;br /&gt;
Um die Pumpe für Testzwecke oder manuell einzuschalten ist der Taster S2 vorgesehen.&lt;br /&gt;
&lt;br /&gt;
= Features =&lt;br /&gt;
* Batteriebetrieben&lt;br /&gt;
* Über PC konfigurierbar&lt;br /&gt;
* Einfacher Aufbau ohne komplizierte Feuchtemessung&lt;br /&gt;
&lt;br /&gt;
= Aufbau =&lt;br /&gt;
== Mechanisch ==&lt;br /&gt;
Der Hauptteilbesteht aus einer Membranpume, die mit einem Wasser-Vorratsbehälter verbunden ist. Es ist darauf zu achten, dass eine Membranpumpe von sich aus nicht sperrt, das heisst wenn der Wasserspiegel im Vorratsbehälter höher ist als der in der Pfalnze so fliesst Wasser von alleine! Als Wasserverteiler dient ein festes Kunststoffröhrchen mit seitlich gebohrten Löchern.&lt;br /&gt;
&lt;br /&gt;
=== Fotos des Aufbaus ===&lt;br /&gt;
[[Bild:Bewaesserung_Aufbau.jpg|center|thumb|200px|Aufbau]]&lt;br /&gt;
[[Bild:Bewaesserung_Wasserverteiler.jpg|center|thumb|200px|Wasserverteiler]]&lt;br /&gt;
&lt;br /&gt;
Die Schwedenflaggen gibt übrigens wie auch den Wasserbehälter in der Ikea (Ursprünglicher Verwendungszweck: Aufbewahrungsbox für Zucker usw.)&lt;br /&gt;
&lt;br /&gt;
== Hardware ==&lt;br /&gt;
Die generelle Funktion sollte aus dem Schema erkennbar sein, hier wird nur auf ein paar spezielle Sachen hingewiesen. Generell kann die Schaltung in folgende Teile unterteilt werden:&lt;br /&gt;
* Spannungsregelung 5V&lt;br /&gt;
* Schalter, Taster und LED&lt;br /&gt;
* Prozessor mit Uhrenquarz&lt;br /&gt;
* RS232 Kommunikation&lt;br /&gt;
* Ansteuerung der Pumpe mit StepUp Konverter&lt;br /&gt;
&lt;br /&gt;
=== Schema ===&lt;br /&gt;
[[Bild:Bewaesserung_Schema.png|center|thumb|200px|Schema]]&lt;br /&gt;
&lt;br /&gt;
=== Spezialitäten der Schaltung ===&lt;br /&gt;
Im Betrieb ist der grösste Stromverbraucher der MAX232, deshalb kann diesem die Betriebsspannung mit dem Schalter S1 weggenommen werden, zugleich wird auch die Kommunikation Softwaremässig deaktiviert.&lt;br /&gt;
&lt;br /&gt;
Um die Akkuspannung zu Messen ist ein spezieller Spannungsteiler (R1, R6) vorhanden. R1wird nur gerade während der Messung auf Low gezogen, damit wird erreicht dass der Ruhestrom nur gerade (Vbatt – 5V) / R6 beträgt und nicht Vbatt / (R1 + R6) wie wenn der Widerstand konstant auf GND wäre, was einen erheblichen Unterschied macht.&lt;br /&gt;
&lt;br /&gt;
=== Eventuelle Anpassungen der Hardware ===&lt;br /&gt;
Der StepUp Wandler muss natürlich an die Pumpenspannung angepasst werden. Falls man eine genügend hohe Spannung zur verfügung hat kann man auch den FET Q2 durch einen Leistungsfet ersetzen und die Pumpe oder ein Relais direkt schalten.&lt;br /&gt;
&lt;br /&gt;
=== Fotos der Hardware ===&lt;br /&gt;
[[Bild:Bewaesserung_Frontplatte.jpg|center|thumb|200px|Frontplatte]]&lt;br /&gt;
[[Bild:Bewaesserung_Rueckplatte.jpg|center|thumb|200px|Rückplatte]]&lt;br /&gt;
[[Bild:Bewaesserung_Innenleben.jpg|center|thumb|200px|Innenleben]]&lt;br /&gt;
&lt;br /&gt;
= Software =&lt;br /&gt;
Die Software ist komplett in C geschrieben und mehr auf einfachheit als volle optimierung ausgerichtet, das erklärt auch dass die 4K des Atmega48 rand voll sind. Alle Einstellungen ausser der aktuellen Zeit und dem aktuellen Wochentag werden im EEPROM abgespeichet und sind nache einem Stomausfall wieder vorhanden.&lt;br /&gt;
&lt;br /&gt;
= Kommunikation =&lt;br /&gt;
Die Kommunikation verläuft über RS232 und kann mit jedem &amp;quot;anständigen&amp;quot; Terminalprogramm konfiguriert werden. Ich empfehle für diesen Zweck das kostenlose Termite [[http://www.compuphase.com/software_termite.htm]] für Windows.&lt;br /&gt;
&lt;br /&gt;
== Terminaleinstellungen ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|- &lt;br /&gt;
! Baudrate&lt;br /&gt;
| 2400&lt;br /&gt;
|- &lt;br /&gt;
! Daten Bits&lt;br /&gt;
| 8&lt;br /&gt;
|- &lt;br /&gt;
! Stop Bits&lt;br /&gt;
| 1&lt;br /&gt;
|- &lt;br /&gt;
! Parity Bit&lt;br /&gt;
| keins&lt;br /&gt;
|- &lt;br /&gt;
! Flusssteuerung&lt;br /&gt;
| keine&lt;br /&gt;
|- &lt;br /&gt;
! Zeilenumbruch&lt;br /&gt;
| CR &amp;lt;nowiki&amp;gt;0x0d&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|- &lt;br /&gt;
|}&lt;br /&gt;
[[Bild:Bewaesserung_Termite_Settings.png|center|thumb|200px|Terminaleinstellungen]]&lt;br /&gt;
&lt;br /&gt;
== Kommunikation starten ==&lt;br /&gt;
Die Kommunikation wird gestartet indem man den Befehl &amp;quot;status&amp;quot; sendet, danach sollte etwa folgendes zurückkommen:&lt;br /&gt;
[[Bild:Bewaesserung_Termite_Window.png|center|thumb|200px|Kommunikation]]&lt;br /&gt;
&lt;br /&gt;
== Parameter ==&lt;br /&gt;
::{|  class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
! Befehl || Parameter || Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;nowiki&amp;gt;time&amp;lt;/nowiki&amp;gt;    || &amp;lt;nowiki&amp;gt;hh:mm&amp;lt;/nowiki&amp;gt; || Aktuelle Uhrzeit&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;nowiki&amp;gt;weekday&amp;lt;/nowiki&amp;gt;    || &amp;lt;nowiki&amp;gt;x&amp;lt;/nowiki&amp;gt; || Wochentag (1=Mo 7=So)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;nowiki&amp;gt;days&amp;lt;/nowiki&amp;gt;    || &amp;lt;nowiki&amp;gt;xxxxxxx&amp;lt;/nowiki&amp;gt; || Wochentage an denen die Pumpe aktiv ist. 0 oder 1 für jeden Wochentag Mo – So&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;nowiki&amp;gt;active&amp;lt;/nowiki&amp;gt;    || &amp;lt;nowiki&amp;gt;sss&amp;lt;/nowiki&amp;gt; || Einschaltzeit in Sekunden in der die Pumpe aktiv ist&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;nowiki&amp;gt;daytime&amp;lt;/nowiki&amp;gt;    || &amp;lt;nowiki&amp;gt;hh:mm&amp;lt;/nowiki&amp;gt; || Tageszeit zu der die Pumpe beginnt zu laufen&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Wichtig ist, dass man die Anzahl Zeichen einhält, will man also eine Einschaltzzeit vo 2 Sekunden erreichen, so muss &amp;lt;nowiki&amp;gt;active 002&amp;lt;/nowiki&amp;gt; gesendet werden.&lt;br /&gt;
&lt;br /&gt;
= Alternativen / Erweiterungen =&lt;br /&gt;
Natürlich kann dieses Projekt nicht nur als Steuerung für eine Pumpe dienen, sondern als beliebige Tageszeitschaltuhr.&lt;br /&gt;
&lt;br /&gt;
= Downloads =&lt;br /&gt;
Schema und Software sind OpenSource und können vom SVN heruntergeladen werden. Die Ordnerstruktur ist in der README Datei im Rootverzeichnis erklärt. http://www.mikrocontroller.net/svnbrowser/bewaesserung/&lt;/div&gt;</summary>
		<author><name>80.72.130.218</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=ENC28J60&amp;diff=46353</id>
		<title>ENC28J60</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=ENC28J60&amp;diff=46353"/>
		<updated>2010-04-16T11:46:57Z</updated>

		<summary type="html">&lt;p&gt;80.72.130.218: /* Reichelt */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Der ENC28J60 ist ein Ethernet-Controller von Microchip. Das besondere ist die handliche Bauform (unter anderem PDIP-28) und das SPI-Interface.&lt;br /&gt;
&lt;br /&gt;
==Projekte==&lt;br /&gt;
*[http://avr.auctionant.de/avrETH1/ winziger Webserver (komplett SMD, mehrseitig) mit enc28j60 und atmega32(avrETH1)] (02.03.2006)&lt;br /&gt;
*[http://home.arcor.de/fuenfundachtzig/me/me.htm E-Mail-Client mit dem ENC 28J60 und dem ATmega32 (ME)] (28.03.2006)&lt;br /&gt;
*[http://www.lochraster.org/etherrape generische Platform (ohne SMD-Teile) für viele Applikationen (&amp;quot;etherrape&amp;quot;), enc28j60 mit atmega644] (29.11.2006)&lt;br /&gt;
* https://berlin.ccc.de/wiki/Mikrocontroller (barebone, kein Zubehör bestückt, ohne SMD)&lt;br /&gt;
* [http://www.ulrichradig.de/home/index.php/avr/eth_m32_ex ATmega32/644 Webserver ohne SMD!] (23.11.2007)&lt;br /&gt;
* [http://www.triplay.de/zeigeprojekt.php?id=22 ATmega644 Webserver und Webcam auf einseitiger SMD Platine. Mit Tipps zur Programmierung des enc28j60] (16.12.2007)&lt;br /&gt;
* [[Miniwebserver]]&lt;br /&gt;
* [http://www.ethersex.de/ Umfassendes Projekt mit IPv6, RFM12 und vieles mehr]&lt;br /&gt;
* [http://wiki.neo-guerillaz.de/mediawiki Kleine Platine mit allem was man braucht. Bis auf den AVR alles DIL/DIP. Komplett GPL/OpenSource] (12.10.2008)&lt;br /&gt;
&lt;br /&gt;
==Bezugsquellen==&lt;br /&gt;
&lt;br /&gt;
=== Reichelt ===&lt;br /&gt;
*  [http://www.reichelt.de/?;ACTION=3;LA=2;GROUPID=2946;ARTICLE=89339;SID=286m1Z4KwQARwAACMOS0g402d9ed30ed809e838679a59c8f75aac ENC 28J60 SO-28] 2,55€&lt;br /&gt;
* [http://www.reichelt.de/?;ACTION=3;LA=2;GROUPID=2946;ARTICLE=89340;SID=286m1Z4KwQARwAACMOS0g402d9ed30ed809e838679a59c8f75aac ENC 28J60 DIL-28] &#039;&#039;Stand 2010-04-16 nicht lieferbar&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Mikrocontroller.net ===&lt;br /&gt;
* [http://shop.mikrocontroller.net/?product_id=65 Adapterplatine mit ENC28J60 und Ethernet-Buchse]&lt;br /&gt;
&lt;br /&gt;
===[[Elektronik-Versender#csd-electronics|csd-electronics]]===&lt;br /&gt;
*ENC28J60 DIP28S 4,39€ (Best.Nr.: 30362)&lt;br /&gt;
*ENC28J60 SOIC28 4,39€ (Best.Nr.: 30363)&lt;br /&gt;
*ENC28J60 SSOP28 4,95€ (Best.Nr.: 30365)&lt;br /&gt;
*ENC28J60 QFN28 6,95€ (Best.Nr.: 30364)&lt;br /&gt;
*MagJack mit 4 Leds 3,45€ (Best.Nr.: 015-54085)&lt;br /&gt;
*MagJack mit 2 Leds 4,95€ (Best.Nr.: 015-54084)&lt;br /&gt;
*PulseJack mit Leds 2,40€ (Best.Nr.: 015-54087)&lt;br /&gt;
*25 MHz-Quarz SMD (Grundton) 0,49€ (Best.Nr.: 14-4S25,000MHZ)&lt;br /&gt;
*25 MHz-Quarz (Grundton) 0,35€ (Best.Nr.: 14-US25,000MHZ)&lt;br /&gt;
*49.9 Ohm 1% Widerstand 0805 100 Stk 1,00€ (Best.Nr.: 10-080049)&lt;br /&gt;
&lt;br /&gt;
===[[Elektronik-Versender#Microcontroller-Starterkits|microcontroller-starterkits]]===&lt;br /&gt;
*ENC28J60 SO28 6,50€ (Best.Nr.: 4019)&lt;br /&gt;
*ENC28J60 DIP28 6,50€ (Best.Nr.: 4031)&lt;br /&gt;
*MagJack mit Leds 5,50€ (Best.Nr.: 4276)&lt;br /&gt;
*25 MHz-Quarz (Grundton) 0,60€ (Best.Nr.: 4182)&lt;br /&gt;
&lt;br /&gt;
===[[Elektronik-Versender#Embedit_Mikrocontrollertechnik|Embedit Mikrocontrollertechnik]]===&lt;br /&gt;
*ENC28J60 DIP28 5,99€&lt;br /&gt;
*ENC28J60 SO28 5,99€&lt;br /&gt;
*ENC28J60 QFN28 5,99€&lt;br /&gt;
*Taimag RJLBC-060TC1 RJ45 Buchse mit Übertrager und LEDs 3,99€&lt;br /&gt;
*25 MHz-Quarz HC49U/S (Grundton) 0,50€&lt;br /&gt;
&lt;br /&gt;
===[[Elektronik-Versender#IT-WNS|IT-WNS]]===&lt;br /&gt;
*ENC28J60 DIP28 4,19€&lt;br /&gt;
*ENC28J60 SO28 4,39€&lt;br /&gt;
*25 MHz-Quarz SMD (Grundton) 0,65€&lt;br /&gt;
*49.9 Ohm 1% Widerstand 0805 Stk 0,03€&lt;br /&gt;
*49.9 Ohm 1% Widerstand bedrahtet Stk 0,09€&lt;br /&gt;
&lt;br /&gt;
===[[Elektronik-Versender#Watterott electronic|Watterott electronic]]===&lt;br /&gt;
*ENC28J60 SOIC28 3,25€&lt;br /&gt;
*ENC28J60 DIL28 3,50€&lt;br /&gt;
*MagJack mit LEDs 2,00€&lt;br /&gt;
*Würth RJ-45 mit Übertrager, 2 Leds und PoE 6,35€&lt;br /&gt;
*Würth RJ-45 mit 2 Leds 1,60€&lt;br /&gt;
*Würth SMD Übertrager für PoE 3,15€&lt;br /&gt;
*25MHz Grundtonquarz HC49 SMD 0,50€&lt;br /&gt;
*25MHz Grundtonquarz CS10 SMD 1,20€&lt;br /&gt;
&lt;br /&gt;
===[[Elektronik-Versender#Pollin_Electronic|Pollin Electronic]]===&lt;br /&gt;
&lt;br /&gt;
* [http://www.pollin.de/shop/shop.php?cf=detail.php&amp;amp;pg=OA==&amp;amp;a=MTQ5OTgxOTk=&amp;amp;w=OTk4OTU4&amp;amp;ts=0  Komplettbausatz AVR-NET-IO] mit Platine, ENC28J60, AVR ATmega32, MagJack usw. 19,95€&lt;br /&gt;
* [http://www.pollin.de/shop/detail.php?pg=NQ==&amp;amp;a=NzQxOTk4OTk= ENC28J60] einzelnes IC DIP28. 3,20€&lt;br /&gt;
* [http://www.pollin.de/shop/detail.php?pg=NQ==&amp;amp;a=ODk5OTQ1OTk= RJ45-Modularbuchse] mit integriertem Impulsübertrager, 2 LEDs, geschirmt, 8 Pins belegt, abgewinkelt. 1,95€&lt;br /&gt;
&lt;br /&gt;
==Forum==&lt;br /&gt;
*[http://www.mikrocontroller.net/forum/read-4-343017.html#new ENC28J60 Basics (Beispielprogramm in AVRGCC für atmega8)] (29.04.2006)&lt;br /&gt;
*[http://www.mikrocontroller.net/forum/read-1-310134.html#new winziger Webserver mit enc28j60+mega32] (26.02.2006)&lt;br /&gt;
*[http://www.mikrocontroller.net/forum/read-1-179365.html#new Handlicher Ethernet-Controller mit SPI von Microchip] (26.04.2005)&lt;br /&gt;
*[http://www.mikrocontroller.net/forum/read-1-291186.html Eagle Platine mit ENC28J60 und AVR Mega8L]&lt;br /&gt;
*[http://www.mikrocontroller.net/forum/read-1-355428.html LPC2138 + ENC28J60] (23.05.2006)&lt;br /&gt;
*[http://www.mikrocontroller.net/forum/read-1-402627.html I/O über Ethernet mit einem ENC28J60] (19.08.2006)&lt;br /&gt;
*[http://www.mikrocontroller.net/topic/82127  Webserver ATmega32/644DIP ENC28J60 (ohne SMD!)] (14.11.2007)&lt;br /&gt;
*[http://www.mikrocontroller.net/topic/100177 Erweiterbares Ethernetboard mit MMC/SD-Slot und USB] (17.05.2008)&lt;br /&gt;
*[http://www.mikrocontroller.net/topic/109988 AVR für wenig Geld im LAN] (03.09.2008)&lt;br /&gt;
*[http://www.mikrocontroller.net/topic/131825 Die andere Firmware für AVR-NET IO] (15.03.2009)&lt;br /&gt;
&lt;br /&gt;
==Hardware==&lt;br /&gt;
*[http://www.olimex.com/dev/images/enc28j60-sch.gif Minimalbeschaltung] (Quelle: Olimex)&lt;br /&gt;
*[http://www.b-redemann.de/produkte-ethernet.shtml Bausatz Ethernetmodul mit ENC28J60] (Ohne smds, www.b-redemann.de)&lt;br /&gt;
* Im [http://shop.mikrocontroller.net/ mikrocontroller.net Shop] das Modul von Olimex (22.04.2008)&lt;br /&gt;
*[http://www.ulrichradig.de/ Ulrich Radig] Ethernet ATmega32/644 Experimentierboard (01.09.2008)&lt;br /&gt;
*[http://www.pollin.de/ Pollin] Bausatz AVR-NET-IO, ArtNr 810 058 (01.09.2008)&lt;br /&gt;
*[http://rz-robotics.de/z-lan.html Z-LAN] bei rz-robotics mit 3,3V-Spannungsregler onboard (26.01.2009).&lt;br /&gt;
&lt;br /&gt;
==Software==&lt;br /&gt;
*[http://www.mil.ufl.edu/~chrisarnold/components/microcontrollerBoard/AVR/avrlib/docs/html/ Procyon AVRlib: Network Library ]&lt;br /&gt;
*[http://www.sics.se/~adam/uip/ uIP TCP/IP Stack for Embedded Microcontrollers]&lt;br /&gt;
*[http://www.ulrichradig.de/ Ulrich Radig] Ethernet ATmega32/644 Experimentierboard (01.09.2008)&lt;br /&gt;
*[http://ww1.microchip.com/downloads/en/DeviceDoc/Microchip%20TCPIP%20Stack%20v4.55%20Installer.zip TCP/IP Stack für PIC] von Microchip (26.01.2009)&lt;br /&gt;
* [http://wiki.neo-guerillaz.de Der &amp;quot;Hurrican&amp;quot; TCP/IP-Stack vom OpenMCP-Projekt] von Dirk Broßwick für den ATmega644/644P/2561 (15.03.2009)&lt;br /&gt;
&lt;br /&gt;
==Eagle Lib==&lt;br /&gt;
*[http://www.mikrocontroller.net/topic/51293 Eagle Lib aus dem Forum]&lt;br /&gt;
*[http://www.watterott.com/ENC28J60-SP-DIL28 Eagle Lib von www.watterott.com]&lt;br /&gt;
&lt;br /&gt;
==Datenblatt==&lt;br /&gt;
[http://ww1.microchip.com/downloads/en/DeviceDoc/39662b.pdf Link zum Datenblatt]&lt;br /&gt;
&lt;br /&gt;
==Häufige Fehlerursachen==&lt;br /&gt;
&#039;&#039;&#039;Frage&#039;&#039;&#039;: Mein ENC28J60 baut einen Link auf und empfängt laut RX Activity LED auch Pakete. Allerdings sind PKTIF und EPKTCNT 0x00. Die SPI Kommunikation arbeitet einwandfrei&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Antwort&#039;&#039;&#039;: Die Kondensatoren am Quarz des ENC28J60 spielen eine wichtige Rolle für den Empfang und die Versendung von Paketen. Testweise sollte man den Wert der Kondensatoren verringern (2,2pF haben schon einmal Erfolg gebracht) oder die Kondensatoren komplett entfernen.&lt;br /&gt;
Wenn schnelle HostController eingesetzt werden, muss unbedingt auf das Timing des CS-Anschlusses geachtet werden - beim Zugriff auf PHY und MAC Register muss nach der SPI-Übertragung CS 210ns aktiv bleiben. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Frage&#039;&#039;&#039;: Mein ENC28J60 wird recht warm. Ist er kaputt?&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Antwort&#039;&#039;&#039;: Nein. Schau mal ins Datasheet unter Stromverbrauch. Je nach Gehäusegrösse äussert sich der in &#039;&#039;warm&#039;&#039; bis &#039;&#039;heiss&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Ethernet]]&lt;br /&gt;
[[Kategorie:Bauteile]]&lt;/div&gt;</summary>
		<author><name>80.72.130.218</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=STM32&amp;diff=45916</id>
		<title>STM32</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=STM32&amp;diff=45916"/>
		<updated>2010-04-08T11:49:45Z</updated>

		<summary type="html">&lt;p&gt;80.72.130.218: /* Links, Foren, Communities */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;&lt;br /&gt;
== Allgemeine Infos ==&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Der STM32 ist ein Mikrocontroller von ST ([www.st.com]http://www.st.com/mcu/inchtml-pages-stm32.html) mit einer 32-Bit ARM Cortex-M3 CPU. (http://www.arm.com/products/processors/cortex-m/index.php). Diese Architektur ist speziell für den Einsatz in Microcontrollern neu entwickelt, und löst damit die bisherigen ARM7 basierten Controller weitestgehend ab.&lt;br /&gt;
Den STM32 gibt es von ST in unzähligen Varianten mit variabler Peripherie und verschiedenen Gehäusegrössen und -formen. &lt;br /&gt;
Durch u.a. die geringe benötigte Chipfläche des Core ist es ST möglich, eine 32 Bit-CPU für weniger als 1 EUR an zu bieten.&lt;br /&gt;
* Cortex-M3 Kern&lt;br /&gt;
* 16KB ... 1MB Flash-ROM und bis zu 96KB SRAM&lt;br /&gt;
* Gehäuse 36 ... 144 Pins als QFN, LQFP und BGA&lt;br /&gt;
* Derzeit bis 72MHz, Modelle bis 120MHz sind angekündigt&lt;br /&gt;
* Externes Businterface&lt;br /&gt;
* Spannungsbereich 2,0 ... 3,6V&lt;br /&gt;
* Bis zu 112 IOs, viele davon 5V-tolerant&lt;br /&gt;
* Interner kalibrierter RC-Oszillator mit 8MHz&lt;br /&gt;
* Externer Quarz&lt;br /&gt;
* Real-Time-Clock mit eigenem Quarz und separater Stromversorgung&lt;br /&gt;
* Bis zu 16 Timer, je Timer bis zu 4 IC/OC/PWM Ausgänge. Davon 2x Motion Control Timer&lt;br /&gt;
* Systick Counter&lt;br /&gt;
* Bis zu 3 12-Bit AD-Wandler mit insgesamt 21 AD-Eingängen&lt;br /&gt;
* Bis zu 2 12-Bit DA-Wandler&lt;br /&gt;
* Bis zu 2 DMA Controller mit jeweils bis zu 12 Kanälen&lt;br /&gt;
* JTAG und SWD (Single Wire Debug) Interface&lt;br /&gt;
* Bis zu 2x I²C&lt;br /&gt;
* Bis zu 5x USART mit LIN, IrDA und Modem Control&lt;br /&gt;
* Bis zu 3x SPI&lt;br /&gt;
* Bis zu 2x I²S&lt;br /&gt;
* Bis zu 2x CAN&lt;br /&gt;
* USB 2.0 Full Speed&lt;br /&gt;
* SDIO Interface (z.B. SD-Card Reader)&lt;br /&gt;
* Ethernet&lt;br /&gt;
* Watchdog mit Window-Mode&lt;br /&gt;
* Jedes Peripheriemodul ist separat einschaltbar, wodurch sich erheblich Strom sparen lässt&lt;br /&gt;
* ... (Siehe Datenblätter)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Struktur der Dokumentation: ==&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Als Beispiel der Dokumentation zeige ich mal stellvertretend den STM32F103RC. Die Seite von ST: http://www.st.com/mcu/devicedocs-STM32F103RC-110.html&lt;br /&gt;
Beinhaltet alle nötigen Informationen/Dateien/Dokumente passend zu diesem Prozessor.&lt;br /&gt;
&lt;br /&gt;
Diese Dokumente von ST beschreiben den Controller:&lt;br /&gt;
&lt;br /&gt;
* Datasheet &amp;quot;STM32F103xC/D/E&amp;quot; oder einer anderen Modellreihe&lt;br /&gt;
* Reference Manual &amp;quot;RM0008&amp;quot;&lt;br /&gt;
* Cortex-M3 Programming Manual &amp;quot;PM0056&amp;quot;&lt;br /&gt;
* Flash Programming Reference &amp;quot;PM0042&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Im Datasheet sind die speziellen Eigenschaften eines bestimmten Modells bzw. einer Modellreihe beschrieben und die exakten Daten und Pinouts aufgeführt. Die Peripheriemodule werden nur aufgeführt, nicht detailliert beschrieben. In der Referenz ist der gesamte Controller mit Peripheriemodulen im Detail beschrieben, gültig für alle STM32 Prozessoren. Details zum Prozessor selbst und den nicht STM32-spezifischen mit dem Cortex-M3 Core assoziierten Modulen wie dem Interrupt-Controller und dem Systick-Timer findet man jedoch nicht dort, sondern im Cortex-M3 Manual. Wer nicht die ST Firmware-Library verwendet, der benötigt zusätzlich das Flash Programming Manual für die Betriebsart des Flash-ROMs, d.h. die frequenzabhängige Konfiguration der Waitstates.&lt;br /&gt;
&lt;br /&gt;
Hinzu kommen optionale Dokumente von ARM, die den Cortex-M3 Kern beschreiben.&lt;br /&gt;
Siehe z.B. hier: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.set.cortexm/index.html. Hier gibt es den Opcode wenn man ihn in Assembler programmieren möchte: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0406b/index.html&lt;br /&gt;
&lt;br /&gt;
Zusätzlich sollten auch die Errata Sheets beachtet werden.&lt;br /&gt;
&lt;br /&gt;
Empfohlen sei auch die Appnote: &amp;quot;STM32F10xxx hardware development: getting started&amp;quot; http://www.st.com/stonline/products/literature/an/13675.pdf&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== FW-Lib: ==&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
ST bietet eine umfangreiche FW-LIB Bibliothek. Es ist eine einzige Bibliothek für alle STM32 Derivate. Das ist der große Vorteil von ST. Einmal programmieren und in allen STM32 verwendbar. Alle Funktionen sind gekapselt in einfache Strukturen und Funktionsaufrufe. Somit muss man sich nicht selbst um die Peripherieregister kümmern.&lt;br /&gt;
Die FW-Lib kann ebenfalls von der STM32 Seite kostenlos geladen werden:&lt;br /&gt;
&lt;br /&gt;
* Firmware &amp;quot;STM32F10x_StdPeriph_Lib&amp;quot;&lt;br /&gt;
&lt;br /&gt;
In dem Archiv ist die FW-LIB, zu jeder Peripherie gibt es bis zu 12 Demos und eine Beschreibung als CHM Datei &amp;quot;stm32f10x_stdperiph_lib_um.chm&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== CMSIS: ==&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Parallel zur Firmware-Library gibt es für die &amp;quot;Selbermacher&amp;quot; die CMSIS, die einen Teil der HW und den Core Support abdeckt.&lt;br /&gt;
Im Rahmen des CMSIS Standard (www.onARM.com) wurden die Headerfiles standardisiert, der Zugriff auf die Register erfolgt per &#039;&#039;&#039;Peripheral-&amp;gt;Register&#039;&#039;&#039;. Weiterhin existieren eine Zahl von Helferfunktionen für den NVIC, als auch eine SystemInit - Funktion, welche sich um die PLL kümmert.&lt;br /&gt;
&lt;br /&gt;
== Debug-Interface: ==&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
Als Debug Interface stehen zwei Varianten zur Auswahl:&lt;br /&gt;
* JTAG&lt;br /&gt;
* SWD (Single Wire Debug)&lt;br /&gt;
&lt;br /&gt;
Für JTAG sind 6 Steuerleitungen nötig, für SWD 2 (zzgl GND/3,3V).&lt;br /&gt;
Das SWD Interface verfügt ausserdem über eine weitere Leitung, SWO. Über diesen Kanal kann ein vereinfachtes Trace des Core ermöglicht, sowie printf-like Daten über den ITM Channel 0 geschickt und im Debugger ausgegeben werden.&lt;br /&gt;
&lt;br /&gt;
Die Coresight-Debug-Architektur ermöglicht ein non-invasive debugging, d.h. es können während des Betriebes ohne Beeinflussung des Prozessors Daten vom Speicher gelesen und in selbigen geschrieben werden.&lt;br /&gt;
&lt;br /&gt;
=== Der 10-Polige JTAG-Stecker:===&lt;br /&gt;
&lt;br /&gt;
Ich habe einen 10 Poligen Debug-Stecker entworfen, der alle Varianten sowie einen UART Anschluss enthält:&lt;br /&gt;
&lt;br /&gt;
[[bild:jtag-debug-port10.png]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Die Funktionen:&#039;&#039;&#039;&lt;br /&gt;
* JTAG&lt;br /&gt;
* SWD&lt;br /&gt;
* Debug-UART-Anschluss (verbunden mit einem freien UART vom STM32) (alternativ ein MAX232 Chip dazwischen schalten)&lt;br /&gt;
* Weniger Platzbedarf auf der Platine (Standard-JTAG 20 Polig)&lt;br /&gt;
* Über 4-Poligen Würfel kann der UART benutzt werden (Pin 7/8/9/10)&lt;br /&gt;
* Es kann ein Jumper gesteckt werden für eine Option (Pin 7/8) ohne dass es sich mit dem RS232 Chip beißt (sofern er eingebaut wurde)&lt;br /&gt;
* Über einen 5-Poligen einreihigen Stecker kann SWD (SingleWireDebug) verwendet werden (Pin 1/3/5/7/9)&lt;br /&gt;
* den ganzen Stecker braucht es nur, wenn man den herkömlichen JTAG nutzen möchte.&lt;br /&gt;
* Kurzschlussschutz, da GND und +3V3 nicht gegenüber liegen&lt;br /&gt;
&lt;br /&gt;
In all meinen Projekten verwende ich nur noch diese Anordnung, denn sie ist einfach praktisch. Alles drauf und die Pins sind perfekt angeordnet für jede Art der Anwendung.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Vorteile: ==&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&#039;&#039;&#039;Vorteile gegenüber ARM7:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Interrupt-Controller jetzt Teil des Prozessors (als Core Peripheral), die Vector Table ist jetzt eine echte Vector Tabelle (keine jmps o.ä. wie bei ARM7). Durch automatismen zwischen Core und NVIC (auto register save r0..r3, lr, sp, pc) bei Interrupt Entry wird eine deutlich schnellere Ausführungszeit bei Interrupts erreicht. Der Interrupt Code muss sich nicht mehr selbst um die Sicherung der o.g. Register kümmern. Sind vor Beendigung einer ISR (d.h. Rücksprung zum User Code) weitere Interrupts pending, so werden diese ausgeführt, ohne dass eine komplette pop-push-sequenz der Register notwendig ist.&lt;br /&gt;
* Thumb-2 Befehlssatz wird schneller ausgeführt&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Vorteile gegenüber LPC1700 und LPC1300:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Flexiblere Gehäuseformen mit mehr Peripherie bei kleinen Gehäusen&lt;br /&gt;
* Genauerer ADC, insbesondere gegenüber LPC1300&lt;br /&gt;
* Flexiblere Varianten der Peripherie &amp;gt;&amp;gt; bei weniger einen deutlichen Preisvorteil&lt;br /&gt;
* ab 0,85 EUR (Stand 2010)&lt;br /&gt;
&#039;&#039;&#039;Nachteil gegenüber LPC1700:&#039;&#039;&#039;&lt;br /&gt;
* Nur 72 MHz statt 100 MHz Taktfrequenz&lt;br /&gt;
&#039;&#039;&#039;Vorteile gegenüber anderen &amp;quot;Kleinen&amp;quot; wie z.B. PIC, Atmel usw.&#039;&#039;&#039;&lt;br /&gt;
* nahezu gleicher Preis bei Hobby Anwendungen&lt;br /&gt;
* 32 Bit ohne Umwege in Assembler rechenbar&lt;br /&gt;
* bessere Peripherie&lt;br /&gt;
* ... und weitere 1000 Punkte ...&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Nachteil für Hoppy-Anwender&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Nicht direkt &amp;quot;Steckbrettauglich&amp;quot;, da kein DIL Gehäuse verfügbar. Der ebay-Shop dipmicro führt jedoch sehr günstige Lötadapter für Umsetzung von LQFP48 auf DIP48.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Software/Programmierung: ==&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
Als Programmieroberfläche kann eine kostenlose Struktur verwendet werden (wie meinen?):&lt;br /&gt;
&lt;br /&gt;
* Eclipse&lt;br /&gt;
* Coudesourcery Light&lt;br /&gt;
* OpenOCD&lt;br /&gt;
* Yagarto Tools&lt;br /&gt;
* Eclipse Plugin &amp;quot;GDB Hardware Debugging&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Folgende Umgebungen sind als Demoversion (32k Codesize) verfügbar, idR sind dutzende von Examples dabei:&lt;br /&gt;
&lt;br /&gt;
* Keil µVision (www.keil.com)&lt;br /&gt;
* IAR (www.iar.com)&lt;br /&gt;
&lt;br /&gt;
Programmieradapter&lt;br /&gt;
* J-Link / J-Trace Cortex-M3  (www.segger.com), als NonComercial für ca. 60,- zu haben, läuft in µVision, IAR, gdb&lt;br /&gt;
* z.B. OpenOCD ARM-USB-OCD (nicht kostenlos)&lt;br /&gt;
* Keil ULINK2, ULINK pro&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Installation für STM32 ===&lt;br /&gt;
&lt;br /&gt;
* Eclipse &amp;quot;Galileo&amp;quot; installation:&lt;br /&gt;
    http://www.eclipse.org/ &amp;gt;&amp;gt; Downloads &amp;gt;&amp;gt; &amp;quot;Eclipse IDE for C/C++ Developers (79 MB)&amp;quot;&lt;br /&gt;
    http://www.eclipse.org/downloads/download.php?file=/technology/epp/downloads/release/galileo/SR1/eclipse-cpp-galileo-SR1-win32.zip&lt;br /&gt;
    Entpacken der Datei eclipse-cpp-galileo-SR1-win32.zip nach &amp;quot;C:\WinARM\&amp;quot; (Ordner neu erstellen)&lt;br /&gt;
&lt;br /&gt;
* Yagarto Tools:&lt;br /&gt;
    http://www.yagarto.de/ &amp;gt;&amp;gt; &amp;quot;Download (for Windows)&amp;quot; &amp;gt;&amp;gt; &amp;quot;YAGARTO Tools&amp;quot;&lt;br /&gt;
    http://www.yagarto.de/download/yagarto/yagarto-tools-20091223-setup.exe&lt;br /&gt;
    Installieren, Auswahl Verzeichnis &amp;quot;C:\WinARM\yagarto-tools&amp;quot;&lt;br /&gt;
&lt;br /&gt;
* CodeSourcery:&lt;br /&gt;
    http://www.codesourcery.com/ &amp;gt;&amp;gt; Products&amp;gt;Sourcery G++&amp;gt;Editions&amp;gt;Lite &amp;gt;&amp;gt; Try Now&lt;br /&gt;
    http://www.codesourcery.com/downloads/public/public/gnu_toolchain/arm-none-eabi/arm-2009q3-68-arm-none-eabi.exe&lt;br /&gt;
    Installieren, Auswahl Verzeichnis &amp;quot;C:\WinARM\CodeSourcery&amp;quot;&lt;br /&gt;
&lt;br /&gt;
* OpenOCD, kompilliert von Martin-Thomas:&lt;br /&gt;
    http://www.siwawi.arubi.uni-kl.de/avr_projects/arm_projects/winarmtests/&lt;br /&gt;
    Die letzte Version ist &amp;quot;dont_download_this_OpenOCD_package_V0_3_1_mthomas.zip&amp;quot;&lt;br /&gt;
    Die aktuellste ist im Sourceforge als Quelldateien.&lt;br /&gt;
&lt;br /&gt;
* ST Firmware:&lt;br /&gt;
    http://www.st.com &amp;gt;&amp;gt; Auswahl CPU STM32F103xxx &amp;gt;&amp;gt; &amp;quot;Firmware&amp;quot; &amp;quot;STM32F10x_StdPeriph_Lib&amp;quot;&lt;br /&gt;
    http://www.st.com/mcu/devicedocs-STM32F103RC-110.html&lt;br /&gt;
    Das ZIP &amp;quot;stm32f10x_stdperiph_lib.zip&amp;quot; Entpacken nach &amp;quot;C:\WinARM\examples\stm32_FW3.2.0\&lt;br /&gt;
&lt;br /&gt;
Eclipse:&lt;br /&gt;
Help &amp;gt;&amp;gt; Install New Software... &amp;gt;&amp;gt; http://download.eclipse.org/tools/cdt/releases/galileo&lt;br /&gt;
    &amp;quot;Eclipse C/C++ Development Tools&amp;quot; + &amp;quot;Eclipse C/C++ GDB Hardware Debugging&amp;quot; installieren&lt;br /&gt;
&lt;br /&gt;
=== Installation für STM32 auf einem zweiten Rechner (Eclipse/GCC Installation):===&lt;br /&gt;
* Kopieren des Verzeichnisses C:\WinARM\&lt;br /&gt;
* Die PATH-Variable in der Systemsteuerung mit den C:\WinARM.... Verzeichnissen nachführen&lt;br /&gt;
* Fertig.&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Demo-Projekte: ==&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
Martin Thomas hat ein umfangreiches Projekt erstellt, in der die Eclipse Einstellungen enthalten sind:&lt;br /&gt;
&lt;br /&gt;
&amp;quot;ChaN&#039;s FAT-Module with STM32 SPI&amp;quot;&lt;br /&gt;
http://www.siwawi.arubi.uni-kl.de/avr_projects/arm_projects/arm_memcards/index.html&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
== Errata, Tipps und Tricks ==&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
* AD-Wandler PA0: Im Errata steht, dass hier Fehler in der Wandlung entstehen könnten, also einen anderen Pin verwenden.&lt;br /&gt;
* CAN-Bus PD0/PD1: Remap geht erst ab der 100-Pin-Version. Steht im RM0008 unter 7.3.3. Alle Infos von RM0008 7.3.x sind interssant&lt;br /&gt;
&lt;br /&gt;
== Bezugsquellen ==&lt;br /&gt;
&lt;br /&gt;
=== Controller ===&lt;br /&gt;
Versandhäuser für Privatpersonen:&lt;br /&gt;
* Budelmann Elektronik: http://www.budelmann-elektronik.com (beispielsweise STM32F103RET6 9,00€/Stück, aufgelötet auf SMD-Adapterplatine 12,00€/Stück, momentan nur Anfrage über Kontaktformular möglich)&lt;br /&gt;
* Darisus: http://darisusgmbh.de/shop/index.php?cat=c2692_ARM-Cortex.html&lt;br /&gt;
* Sander: http://www.sander-electronic.de/be00069.html&lt;br /&gt;
* TME.eu: http://www.tme.eu/de/katalog/index.phtml#cleanParameters%3D1%26search%3DSTM32F10%26bf_szukaj%3D+&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Gewerblich liefern natürlich viele wie Farnell, Digikey usw..&lt;br /&gt;
&lt;br /&gt;
=== Evaluation-Boards ===&lt;br /&gt;
* http://shop.embedded-projects.net/index.php?module=artikel&amp;amp;action=gruppe&amp;amp;id=14&lt;br /&gt;
* http://www.watterott.com/de/Boards-Kits/ARM/ARM-Cortex-M3&lt;br /&gt;
* http://www.sander-electronic.de/es0028.html&lt;br /&gt;
* http://www.mikrocontroller.net/articles/MP32F103-Stick:_Ein_Mini-Mikrocontroller-Board_mit_USB_und_bis_zu_4MB_Datenspeicher&lt;br /&gt;
* http://www.futurlec.com/STM32_Development_Board.shtml&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Links, Foren, Communities ==&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
* Diskussion zum Artikel: http://www.mikrocontroller.net/topic/173753&lt;br /&gt;
* Natürlich hier: http://www.mikrocontroller.net/forum/mikrocontroller-elektronik?filter=ARM*+STM32*+Cortex*&lt;br /&gt;
* https://my.st.com/public/STe2ecommunities/mcu/Lists/ARM%20CortexM3%20STM32/AllItems.aspx&lt;br /&gt;
* http://www.stm32circle.com/hom/index.php&lt;/div&gt;</summary>
		<author><name>80.72.130.218</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=STM32&amp;diff=45915</id>
		<title>STM32</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=STM32&amp;diff=45915"/>
		<updated>2010-04-08T11:49:15Z</updated>

		<summary type="html">&lt;p&gt;80.72.130.218: /* STM32 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;&lt;br /&gt;
== Allgemeine Infos ==&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Der STM32 ist ein Mikrocontroller von ST ([www.st.com]http://www.st.com/mcu/inchtml-pages-stm32.html) mit einer 32-Bit ARM Cortex-M3 CPU. (http://www.arm.com/products/processors/cortex-m/index.php). Diese Architektur ist speziell für den Einsatz in Microcontrollern neu entwickelt, und löst damit die bisherigen ARM7 basierten Controller weitestgehend ab.&lt;br /&gt;
Den STM32 gibt es von ST in unzähligen Varianten mit variabler Peripherie und verschiedenen Gehäusegrössen und -formen. &lt;br /&gt;
Durch u.a. die geringe benötigte Chipfläche des Core ist es ST möglich, eine 32 Bit-CPU für weniger als 1 EUR an zu bieten.&lt;br /&gt;
* Cortex-M3 Kern&lt;br /&gt;
* 16KB ... 1MB Flash-ROM und bis zu 96KB SRAM&lt;br /&gt;
* Gehäuse 36 ... 144 Pins als QFN, LQFP und BGA&lt;br /&gt;
* Derzeit bis 72MHz, Modelle bis 120MHz sind angekündigt&lt;br /&gt;
* Externes Businterface&lt;br /&gt;
* Spannungsbereich 2,0 ... 3,6V&lt;br /&gt;
* Bis zu 112 IOs, viele davon 5V-tolerant&lt;br /&gt;
* Interner kalibrierter RC-Oszillator mit 8MHz&lt;br /&gt;
* Externer Quarz&lt;br /&gt;
* Real-Time-Clock mit eigenem Quarz und separater Stromversorgung&lt;br /&gt;
* Bis zu 16 Timer, je Timer bis zu 4 IC/OC/PWM Ausgänge. Davon 2x Motion Control Timer&lt;br /&gt;
* Systick Counter&lt;br /&gt;
* Bis zu 3 12-Bit AD-Wandler mit insgesamt 21 AD-Eingängen&lt;br /&gt;
* Bis zu 2 12-Bit DA-Wandler&lt;br /&gt;
* Bis zu 2 DMA Controller mit jeweils bis zu 12 Kanälen&lt;br /&gt;
* JTAG und SWD (Single Wire Debug) Interface&lt;br /&gt;
* Bis zu 2x I²C&lt;br /&gt;
* Bis zu 5x USART mit LIN, IrDA und Modem Control&lt;br /&gt;
* Bis zu 3x SPI&lt;br /&gt;
* Bis zu 2x I²S&lt;br /&gt;
* Bis zu 2x CAN&lt;br /&gt;
* USB 2.0 Full Speed&lt;br /&gt;
* SDIO Interface (z.B. SD-Card Reader)&lt;br /&gt;
* Ethernet&lt;br /&gt;
* Watchdog mit Window-Mode&lt;br /&gt;
* Jedes Peripheriemodul ist separat einschaltbar, wodurch sich erheblich Strom sparen lässt&lt;br /&gt;
* ... (Siehe Datenblätter)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Struktur der Dokumentation: ==&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Als Beispiel der Dokumentation zeige ich mal stellvertretend den STM32F103RC. Die Seite von ST: http://www.st.com/mcu/devicedocs-STM32F103RC-110.html&lt;br /&gt;
Beinhaltet alle nötigen Informationen/Dateien/Dokumente passend zu diesem Prozessor.&lt;br /&gt;
&lt;br /&gt;
Diese Dokumente von ST beschreiben den Controller:&lt;br /&gt;
&lt;br /&gt;
* Datasheet &amp;quot;STM32F103xC/D/E&amp;quot; oder einer anderen Modellreihe&lt;br /&gt;
* Reference Manual &amp;quot;RM0008&amp;quot;&lt;br /&gt;
* Cortex-M3 Programming Manual &amp;quot;PM0056&amp;quot;&lt;br /&gt;
* Flash Programming Reference &amp;quot;PM0042&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Im Datasheet sind die speziellen Eigenschaften eines bestimmten Modells bzw. einer Modellreihe beschrieben und die exakten Daten und Pinouts aufgeführt. Die Peripheriemodule werden nur aufgeführt, nicht detailliert beschrieben. In der Referenz ist der gesamte Controller mit Peripheriemodulen im Detail beschrieben, gültig für alle STM32 Prozessoren. Details zum Prozessor selbst und den nicht STM32-spezifischen mit dem Cortex-M3 Core assoziierten Modulen wie dem Interrupt-Controller und dem Systick-Timer findet man jedoch nicht dort, sondern im Cortex-M3 Manual. Wer nicht die ST Firmware-Library verwendet, der benötigt zusätzlich das Flash Programming Manual für die Betriebsart des Flash-ROMs, d.h. die frequenzabhängige Konfiguration der Waitstates.&lt;br /&gt;
&lt;br /&gt;
Hinzu kommen optionale Dokumente von ARM, die den Cortex-M3 Kern beschreiben.&lt;br /&gt;
Siehe z.B. hier: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.set.cortexm/index.html. Hier gibt es den Opcode wenn man ihn in Assembler programmieren möchte: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0406b/index.html&lt;br /&gt;
&lt;br /&gt;
Zusätzlich sollten auch die Errata Sheets beachtet werden.&lt;br /&gt;
&lt;br /&gt;
Empfohlen sei auch die Appnote: &amp;quot;STM32F10xxx hardware development: getting started&amp;quot; http://www.st.com/stonline/products/literature/an/13675.pdf&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== FW-Lib: ==&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
ST bietet eine umfangreiche FW-LIB Bibliothek. Es ist eine einzige Bibliothek für alle STM32 Derivate. Das ist der große Vorteil von ST. Einmal programmieren und in allen STM32 verwendbar. Alle Funktionen sind gekapselt in einfache Strukturen und Funktionsaufrufe. Somit muss man sich nicht selbst um die Peripherieregister kümmern.&lt;br /&gt;
Die FW-Lib kann ebenfalls von der STM32 Seite kostenlos geladen werden:&lt;br /&gt;
&lt;br /&gt;
* Firmware &amp;quot;STM32F10x_StdPeriph_Lib&amp;quot;&lt;br /&gt;
&lt;br /&gt;
In dem Archiv ist die FW-LIB, zu jeder Peripherie gibt es bis zu 12 Demos und eine Beschreibung als CHM Datei &amp;quot;stm32f10x_stdperiph_lib_um.chm&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== CMSIS: ==&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Parallel zur Firmware-Library gibt es für die &amp;quot;Selbermacher&amp;quot; die CMSIS, die einen Teil der HW und den Core Support abdeckt.&lt;br /&gt;
Im Rahmen des CMSIS Standard (www.onARM.com) wurden die Headerfiles standardisiert, der Zugriff auf die Register erfolgt per &#039;&#039;&#039;Peripheral-&amp;gt;Register&#039;&#039;&#039;. Weiterhin existieren eine Zahl von Helferfunktionen für den NVIC, als auch eine SystemInit - Funktion, welche sich um die PLL kümmert.&lt;br /&gt;
&lt;br /&gt;
== Debug-Interface: ==&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
Als Debug Interface stehen zwei Varianten zur Auswahl:&lt;br /&gt;
* JTAG&lt;br /&gt;
* SWD (Single Wire Debug)&lt;br /&gt;
&lt;br /&gt;
Für JTAG sind 6 Steuerleitungen nötig, für SWD 2 (zzgl GND/3,3V).&lt;br /&gt;
Das SWD Interface verfügt ausserdem über eine weitere Leitung, SWO. Über diesen Kanal kann ein vereinfachtes Trace des Core ermöglicht, sowie printf-like Daten über den ITM Channel 0 geschickt und im Debugger ausgegeben werden.&lt;br /&gt;
&lt;br /&gt;
Die Coresight-Debug-Architektur ermöglicht ein non-invasive debugging, d.h. es können während des Betriebes ohne Beeinflussung des Prozessors Daten vom Speicher gelesen und in selbigen geschrieben werden.&lt;br /&gt;
&lt;br /&gt;
=== Der 10-Polige JTAG-Stecker:===&lt;br /&gt;
&lt;br /&gt;
Ich habe einen 10 Poligen Debug-Stecker entworfen, der alle Varianten sowie einen UART Anschluss enthält:&lt;br /&gt;
&lt;br /&gt;
[[bild:jtag-debug-port10.png]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Die Funktionen:&#039;&#039;&#039;&lt;br /&gt;
* JTAG&lt;br /&gt;
* SWD&lt;br /&gt;
* Debug-UART-Anschluss (verbunden mit einem freien UART vom STM32) (alternativ ein MAX232 Chip dazwischen schalten)&lt;br /&gt;
* Weniger Platzbedarf auf der Platine (Standard-JTAG 20 Polig)&lt;br /&gt;
* Über 4-Poligen Würfel kann der UART benutzt werden (Pin 7/8/9/10)&lt;br /&gt;
* Es kann ein Jumper gesteckt werden für eine Option (Pin 7/8) ohne dass es sich mit dem RS232 Chip beißt (sofern er eingebaut wurde)&lt;br /&gt;
* Über einen 5-Poligen einreihigen Stecker kann SWD (SingleWireDebug) verwendet werden (Pin 1/3/5/7/9)&lt;br /&gt;
* den ganzen Stecker braucht es nur, wenn man den herkömlichen JTAG nutzen möchte.&lt;br /&gt;
* Kurzschlussschutz, da GND und +3V3 nicht gegenüber liegen&lt;br /&gt;
&lt;br /&gt;
In all meinen Projekten verwende ich nur noch diese Anordnung, denn sie ist einfach praktisch. Alles drauf und die Pins sind perfekt angeordnet für jede Art der Anwendung.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Vorteile: ==&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&#039;&#039;&#039;Vorteile gegenüber ARM7:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Interrupt-Controller jetzt Teil des Prozessors (als Core Peripheral), die Vector Table ist jetzt eine echte Vector Tabelle (keine jmps o.ä. wie bei ARM7). Durch automatismen zwischen Core und NVIC (auto register save r0..r3, lr, sp, pc) bei Interrupt Entry wird eine deutlich schnellere Ausführungszeit bei Interrupts erreicht. Der Interrupt Code muss sich nicht mehr selbst um die Sicherung der o.g. Register kümmern. Sind vor Beendigung einer ISR (d.h. Rücksprung zum User Code) weitere Interrupts pending, so werden diese ausgeführt, ohne dass eine komplette pop-push-sequenz der Register notwendig ist.&lt;br /&gt;
* Thumb-2 Befehlssatz wird schneller ausgeführt&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Vorteile gegenüber LPC1700 und LPC1300:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Flexiblere Gehäuseformen mit mehr Peripherie bei kleinen Gehäusen&lt;br /&gt;
* Genauerer ADC, insbesondere gegenüber LPC1300&lt;br /&gt;
* Flexiblere Varianten der Peripherie &amp;gt;&amp;gt; bei weniger einen deutlichen Preisvorteil&lt;br /&gt;
* ab 0,85 EUR (Stand 2010)&lt;br /&gt;
&#039;&#039;&#039;Nachteil gegenüber LPC1700:&#039;&#039;&#039;&lt;br /&gt;
* Nur 72 MHz statt 100 MHz Taktfrequenz&lt;br /&gt;
&#039;&#039;&#039;Vorteile gegenüber anderen &amp;quot;Kleinen&amp;quot; wie z.B. PIC, Atmel usw.&#039;&#039;&#039;&lt;br /&gt;
* nahezu gleicher Preis bei Hobby Anwendungen&lt;br /&gt;
* 32 Bit ohne Umwege in Assembler rechenbar&lt;br /&gt;
* bessere Peripherie&lt;br /&gt;
* ... und weitere 1000 Punkte ...&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Nachteil für Hoppy-Anwender&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Nicht direkt &amp;quot;Steckbrettauglich&amp;quot;, da kein DIL Gehäuse verfügbar. Der ebay-Shop dipmicro führt jedoch sehr günstige Lötadapter für Umsetzung von LQFP48 auf DIP48.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Software/Programmierung: ==&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
Als Programmieroberfläche kann eine kostenlose Struktur verwendet werden (wie meinen?):&lt;br /&gt;
&lt;br /&gt;
* Eclipse&lt;br /&gt;
* Coudesourcery Light&lt;br /&gt;
* OpenOCD&lt;br /&gt;
* Yagarto Tools&lt;br /&gt;
* Eclipse Plugin &amp;quot;GDB Hardware Debugging&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Folgende Umgebungen sind als Demoversion (32k Codesize) verfügbar, idR sind dutzende von Examples dabei:&lt;br /&gt;
&lt;br /&gt;
* Keil µVision (www.keil.com)&lt;br /&gt;
* IAR (www.iar.com)&lt;br /&gt;
&lt;br /&gt;
Programmieradapter&lt;br /&gt;
* J-Link / J-Trace Cortex-M3  (www.segger.com), als NonComercial für ca. 60,- zu haben, läuft in µVision, IAR, gdb&lt;br /&gt;
* z.B. OpenOCD ARM-USB-OCD (nicht kostenlos)&lt;br /&gt;
* Keil ULINK2, ULINK pro&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Installation für STM32 ===&lt;br /&gt;
&lt;br /&gt;
* Eclipse &amp;quot;Galileo&amp;quot; installation:&lt;br /&gt;
    http://www.eclipse.org/ &amp;gt;&amp;gt; Downloads &amp;gt;&amp;gt; &amp;quot;Eclipse IDE for C/C++ Developers (79 MB)&amp;quot;&lt;br /&gt;
    http://www.eclipse.org/downloads/download.php?file=/technology/epp/downloads/release/galileo/SR1/eclipse-cpp-galileo-SR1-win32.zip&lt;br /&gt;
    Entpacken der Datei eclipse-cpp-galileo-SR1-win32.zip nach &amp;quot;C:\WinARM\&amp;quot; (Ordner neu erstellen)&lt;br /&gt;
&lt;br /&gt;
* Yagarto Tools:&lt;br /&gt;
    http://www.yagarto.de/ &amp;gt;&amp;gt; &amp;quot;Download (for Windows)&amp;quot; &amp;gt;&amp;gt; &amp;quot;YAGARTO Tools&amp;quot;&lt;br /&gt;
    http://www.yagarto.de/download/yagarto/yagarto-tools-20091223-setup.exe&lt;br /&gt;
    Installieren, Auswahl Verzeichnis &amp;quot;C:\WinARM\yagarto-tools&amp;quot;&lt;br /&gt;
&lt;br /&gt;
* CodeSourcery:&lt;br /&gt;
    http://www.codesourcery.com/ &amp;gt;&amp;gt; Products&amp;gt;Sourcery G++&amp;gt;Editions&amp;gt;Lite &amp;gt;&amp;gt; Try Now&lt;br /&gt;
    http://www.codesourcery.com/downloads/public/public/gnu_toolchain/arm-none-eabi/arm-2009q3-68-arm-none-eabi.exe&lt;br /&gt;
    Installieren, Auswahl Verzeichnis &amp;quot;C:\WinARM\CodeSourcery&amp;quot;&lt;br /&gt;
&lt;br /&gt;
* OpenOCD, kompilliert von Martin-Thomas:&lt;br /&gt;
    http://www.siwawi.arubi.uni-kl.de/avr_projects/arm_projects/winarmtests/&lt;br /&gt;
    Die letzte Version ist &amp;quot;dont_download_this_OpenOCD_package_V0_3_1_mthomas.zip&amp;quot;&lt;br /&gt;
    Die aktuellste ist im Sourceforge als Quelldateien.&lt;br /&gt;
&lt;br /&gt;
* ST Firmware:&lt;br /&gt;
    http://www.st.com &amp;gt;&amp;gt; Auswahl CPU STM32F103xxx &amp;gt;&amp;gt; &amp;quot;Firmware&amp;quot; &amp;quot;STM32F10x_StdPeriph_Lib&amp;quot;&lt;br /&gt;
    http://www.st.com/mcu/devicedocs-STM32F103RC-110.html&lt;br /&gt;
    Das ZIP &amp;quot;stm32f10x_stdperiph_lib.zip&amp;quot; Entpacken nach &amp;quot;C:\WinARM\examples\stm32_FW3.2.0\&lt;br /&gt;
&lt;br /&gt;
Eclipse:&lt;br /&gt;
Help &amp;gt;&amp;gt; Install New Software... &amp;gt;&amp;gt; http://download.eclipse.org/tools/cdt/releases/galileo&lt;br /&gt;
    &amp;quot;Eclipse C/C++ Development Tools&amp;quot; + &amp;quot;Eclipse C/C++ GDB Hardware Debugging&amp;quot; installieren&lt;br /&gt;
&lt;br /&gt;
=== Installation für STM32 auf einem zweiten Rechner (Eclipse/GCC Installation):===&lt;br /&gt;
* Kopieren des Verzeichnisses C:\WinARM\&lt;br /&gt;
* Die PATH-Variable in der Systemsteuerung mit den C:\WinARM.... Verzeichnissen nachführen&lt;br /&gt;
* Fertig.&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Demo-Projekte: ==&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
Martin Thomas hat ein umfangreiches Projekt erstellt, in der die Eclipse Einstellungen enthalten sind:&lt;br /&gt;
&lt;br /&gt;
&amp;quot;ChaN&#039;s FAT-Module with STM32 SPI&amp;quot;&lt;br /&gt;
http://www.siwawi.arubi.uni-kl.de/avr_projects/arm_projects/arm_memcards/index.html&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
== Errata, Tipps und Tricks ==&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
* AD-Wandler PA0: Im Errata steht, dass hier Fehler in der Wandlung entstehen könnten, also einen anderen Pin verwenden.&lt;br /&gt;
* CAN-Bus PD0/PD1: Remap geht erst ab der 100-Pin-Version. Steht im RM0008 unter 7.3.3. Alle Infos von RM0008 7.3.x sind interssant&lt;br /&gt;
&lt;br /&gt;
== Bezugsquellen ==&lt;br /&gt;
&lt;br /&gt;
=== Controller ===&lt;br /&gt;
Versandhäuser für Privatpersonen:&lt;br /&gt;
* Budelmann Elektronik: http://www.budelmann-elektronik.com (beispielsweise STM32F103RET6 9,00€/Stück, aufgelötet auf SMD-Adapterplatine 12,00€/Stück, momentan nur Anfrage über Kontaktformular möglich)&lt;br /&gt;
* Darisus: http://darisusgmbh.de/shop/index.php?cat=c2692_ARM-Cortex.html&lt;br /&gt;
* Sander: http://www.sander-electronic.de/be00069.html&lt;br /&gt;
* TME.eu: http://www.tme.eu/de/katalog/index.phtml#cleanParameters%3D1%26search%3DSTM32F10%26bf_szukaj%3D+&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Gewerblich liefern natürlich viele wie Farnell, Digikey usw..&lt;br /&gt;
&lt;br /&gt;
=== Evaluation-Boards ===&lt;br /&gt;
* http://shop.embedded-projects.net/index.php?module=artikel&amp;amp;action=gruppe&amp;amp;id=14&lt;br /&gt;
* http://www.watterott.com/de/Boards-Kits/ARM/ARM-Cortex-M3&lt;br /&gt;
* http://www.sander-electronic.de/es0028.html&lt;br /&gt;
* http://www.mikrocontroller.net/articles/MP32F103-Stick:_Ein_Mini-Mikrocontroller-Board_mit_USB_und_bis_zu_4MB_Datenspeicher&lt;br /&gt;
* http://www.futurlec.com/STM32_Development_Board.shtml&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Links, Foren, Communities ==&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
* Natürlich hier: http://www.mikrocontroller.net/forum/mikrocontroller-elektronik?filter=ARM*+STM32*+Cortex*&lt;br /&gt;
* https://my.st.com/public/STe2ecommunities/mcu/Lists/ARM%20CortexM3%20STM32/AllItems.aspx&lt;br /&gt;
* http://www.stm32circle.com/hom/index.php&lt;/div&gt;</summary>
		<author><name>80.72.130.218</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=STM32&amp;diff=45910</id>
		<title>STM32</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=STM32&amp;diff=45910"/>
		<updated>2010-04-08T11:30:56Z</updated>

		<summary type="html">&lt;p&gt;80.72.130.218: /* Tipps zur Programmierung */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;&lt;br /&gt;
== STM32 ==&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Der STM32 ist ein Mikrocontroller von ST ([www.st.com]http://www.st.com/mcu/inchtml-pages-stm32.html) mit einer 32-Bit ARM Cortex-M3 CPU. (http://www.arm.com/products/processors/cortex-m/index.php). Diese Architektur ist speziell für den Einsatz in Microcontrollern neu entwickelt, und löst damit die bisherigen ARM7 basierten Controller weitestgehend ab.&lt;br /&gt;
Den STM32 gibt es von ST in unzähligen Varianten mit variabler Peripherie und verschiedenen Gehäusegrössen und -formen. &lt;br /&gt;
Durch u.a. die geringe benötigte Chipfläche des Core ist es ST möglich, eine 32 Bit-CPU für weniger als 1 EUR an zu bieten.&lt;br /&gt;
* Cortex-M3 Kern&lt;br /&gt;
* 16KB ... 1MB Flash-ROM und bis zu 64KB SRAM&lt;br /&gt;
* Gehäuse 36 ... 144 Pins als QFN, LQFP und BGA&lt;br /&gt;
* Derzeit bis 72MHz, Modelle bis 120MHz sind angekündigt&lt;br /&gt;
* Externes Businterface&lt;br /&gt;
* Spannungsbereich 2,0 ... 3,6V&lt;br /&gt;
* Bis zu 112 IOs, viele davon 5V-tolerant&lt;br /&gt;
* Interner kalibrierter RC-Oszillator mit 8MHz&lt;br /&gt;
* Externer Quarz&lt;br /&gt;
* Real-Time-Clock mit eigenem Quarz und separater Stromversorgung&lt;br /&gt;
* Bis zu 11 Timer, je Timer bis zu 4 IC/OC/PWM Ausgänge. Davon 2x Motion Control Timer&lt;br /&gt;
* Systick Counter&lt;br /&gt;
* Bis zu 3 12-Bit AD-Wandler mit insgesamt 16 AD-Eingängen&lt;br /&gt;
* Bis zu 2 12-Bit DA-Wandler&lt;br /&gt;
* Bis zu 2 DMA Controller mit jeweils bis zu 12 Kanälen&lt;br /&gt;
* JTAG und SWD (Single Wire Debug) Interface&lt;br /&gt;
* Bis zu 2x I²C&lt;br /&gt;
* Bis zu 5x USART mit LIN, IrDA und Modem Control&lt;br /&gt;
* Bis zu 3x SPI&lt;br /&gt;
* Bis zu 2x I²S&lt;br /&gt;
* Bis zu 2x CAN&lt;br /&gt;
* USB 2.0 Full Speed&lt;br /&gt;
* SDIO Interface (z.B. SD-Card Reader)&lt;br /&gt;
* Ethernet&lt;br /&gt;
* Watchdog mit Window-Mode&lt;br /&gt;
* Jedes Peripheriemodul ist separat einschaltbar, wodurch sich erheblich Strom sparen lässt&lt;br /&gt;
* ... (Siehe Datenblätter)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Struktur der Dokumentation: ==&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Als Beispiel der Dokumentation zeige ich mal stellvertretend den STM32F103RC. Die Seite von ST: http://www.st.com/mcu/devicedocs-STM32F103RC-110.html&lt;br /&gt;
Beinhaltet alle nötigen Informationen/Dateien/Dokumente passend zu diesem Prozessor.&lt;br /&gt;
&lt;br /&gt;
Diese Dokumente von ST beschreiben den Controller:&lt;br /&gt;
&lt;br /&gt;
* Datasheet &amp;quot;STM32F103xC/D/E&amp;quot; oder einer anderen Modellreihe&lt;br /&gt;
* Reference Manual &amp;quot;RM0008&amp;quot;&lt;br /&gt;
* Cortex-M3 Programming Manual &amp;quot;PM0056&amp;quot;&lt;br /&gt;
* Flash Programming Reference &amp;quot;PM0042&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Im Datasheet sind die speziellen Eigenschaften eines bestimmten Modells bzw. einer Modellreihe beschrieben und die exakten Daten und Pinouts aufgeführt. Die Peripheriemodule werden nur aufgeführt, nicht detailliert beschrieben. In der Referenz ist der gesamte Controller mit Peripheriemodulen im Detail beschrieben, gültig für alle STM32 Prozessoren. Details zum Prozessor selbst und den nicht STM32-spezifischen mit dem Cortex-M3 Core assoziierten Modulen wie dem Interrupt-Controller und dem Systick-Timer findet man jedoch nicht dort, sondern im Cortex-M3 Manual. Wer nicht die ST Firmware-Library verwendet, der benötigt zusätzlich das Flash Programming Manual für die Betriebsart des Flash-ROMs, d.h. die frequenzabhängige Konfiguration der Waitstates.&lt;br /&gt;
&lt;br /&gt;
Hinzu kommen optionale Dokumente von ARM, die den Cortex-M3 Kern beschreiben.&lt;br /&gt;
Siehe z.B. hier: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.set.cortexm/index.html. Hier gibt es den Opcode wenn man ihn in Assembler programmieren möchte: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0406b/index.html&lt;br /&gt;
&lt;br /&gt;
Zusätzlich sollten auch die Errata Sheets beachtet werden.&lt;br /&gt;
&lt;br /&gt;
Empfohlen sei auch die Appnote: &amp;quot;STM32F10xxx hardware development: getting started&amp;quot; http://www.st.com/stonline/products/literature/an/13675.pdf&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== FW-Lib: ==&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
ST bietet eine umfangreiche FW-LIB Bibliothek. Es ist eine einzige Bibliothek für alle STM32 Derivate. Das ist der große Vorteil von ST. Einmal programmieren und in allen STM32 verwendbar. Alle Funktionen sind gekapselt in einfache Strukturen und Funktionsaufrufe. Somit muss man sich nicht selbst um die Peripherieregister kümmern.&lt;br /&gt;
Die FW-Lib kann ebenfalls von der STM32 Seite kostenlos geladen werden:&lt;br /&gt;
&lt;br /&gt;
* Firmware &amp;quot;STM32F10x_StdPeriph_Lib&amp;quot;&lt;br /&gt;
&lt;br /&gt;
In dem Archiv ist die FW-LIB, zu jeder Peripherie gibt es bis zu 12 Demos und eine Beschreibung als CHM Datei &amp;quot;stm32f10x_stdperiph_lib_um.chm&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== CMSIS: ==&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Parallel zur Firmware-Library gibt es für die &amp;quot;Selbermacher&amp;quot; die CMSIS, die einen Teil der HW und den Core Support abdeckt.&lt;br /&gt;
Im Rahmen des CMSIS Standard (www.onARM.com) wurden die Headerfiles standardisiert, der Zugriff auf die Register erfolgt per &#039;&#039;&#039;Peripheral-&amp;gt;Register&#039;&#039;&#039;. Weiterhin existieren eine Zahl von Helferfunktionen für den NVIC, als auch eine SystemInit - Funktion, welche sich um die PLL kümmert.&lt;br /&gt;
&lt;br /&gt;
== Debug-Interface: ==&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
Als Debug Interface stehen zwei Varianten zur Auswahl:&lt;br /&gt;
* JTAG&lt;br /&gt;
* SWD (Single Wire Debug)&lt;br /&gt;
&lt;br /&gt;
Für JTAG sind 6 Steuerleitungen nötig, für SWD 2 (zzgl GND/3,3V).&lt;br /&gt;
Das SWD Interface verfügt ausserdem über eine weitere Leitung, SWO. Über diesen Kanal kann ein vereinfachtes Trace des Core ermöglicht, sowie printf-like Daten über den ITM Channel 0 geschickt und im Debugger ausgegeben werden.&lt;br /&gt;
&lt;br /&gt;
Die Coresight-Debug-Architektur ermöglicht ein non-invasive debugging, d.h. es können während des Betriebes ohne Beeinflussung des Prozessors Daten vom Speicher gelesen und in selbigen geschrieben werden.&lt;br /&gt;
&lt;br /&gt;
=== Der 10-Polige JTAG-Stecker:===&lt;br /&gt;
&lt;br /&gt;
Ich habe einen 10 Poligen Debug-Stecker entworfen, der alle Varianten sowie einen UART Anschluss enthält:&lt;br /&gt;
&lt;br /&gt;
[[bild:jtag-debug-port10.png]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Die Funktionen:&#039;&#039;&#039;&lt;br /&gt;
* JTAG&lt;br /&gt;
* SWD&lt;br /&gt;
* Debug-UART-Anschluss (verbunden mit einem freien UART vom STM32) (alternativ ein MAX232 Chip dazwischen schalten)&lt;br /&gt;
* Weniger Platzbedarf auf der Platine (Standard-JTAG 20 Polig)&lt;br /&gt;
* Über 4-Poligen Würfel kann der UART benutzt werden (Pin 7/8/9/10)&lt;br /&gt;
* Es kann ein Jumper gesteckt werden für eine Option (Pin 7/8) ohne dass es sich mit dem RS232 Chip beißt (sofern er eingebaut wurde)&lt;br /&gt;
* Über einen 5-Poligen einreihigen Stecker kann SWD (SingleWireDebug) verwendet werden (Pin 1/3/5/7/9)&lt;br /&gt;
* den ganzen Stecker braucht es nur, wenn man den herkömlichen JTAG nutzen möchte.&lt;br /&gt;
* Kurzschlussschutz, da GND und +3V3 nicht gegenüber liegen&lt;br /&gt;
&lt;br /&gt;
In all meinen Projekten verwende ich nur noch diese Anordnung, denn sie ist einfach praktisch. Alles drauf und die Pins sind perfekt angeordnet für jede Art der Anwendung.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Vorteile: ==&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&#039;&#039;&#039;Vorteile gegenüber ARM7:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Interrupt-Controller jetzt Teil des Prozessors (als Core Peripheral), die Vector Table ist jetzt eine echte Vector Tabelle (keine jmps o.ä. wie bei ARM7). Durch automatismen zwischen Core und NVIC (auto register save r0..r3, lr, sp, pc) bei Interrupt Entry wird eine deutlich schnellere Ausführungszeit bei Interrupts erreicht. Der Interrupt Code muss sich nicht mehr selbst um die Sicherung der o.g. Register kümmern. Sind vor Beendigung einer ISR (d.h. Rücksprung zum User Code) weitere Interrupts pending, so werden diese ausgeführt, ohne dass eine komplette pop-push-sequenz der Register notwendig ist.&lt;br /&gt;
* Thumb-2 Befehlssatz wird schneller ausgeführt&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Vorteile gegenüber LPC1700 und LPC1300:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Flexiblere Gehäuseformen mit mehr Peripherie bei kleinen Gehäusen&lt;br /&gt;
* Genauerer ADC, insbesondere gegenüber LPC1300&lt;br /&gt;
* Flexiblere Varianten der Peripherie &amp;gt;&amp;gt; bei weniger einen deutlichen Preisvorteil&lt;br /&gt;
* ab 0,85 EUR (Stand 2010)&lt;br /&gt;
&#039;&#039;&#039;Nachteil gegenüber LPC1700:&#039;&#039;&#039;&lt;br /&gt;
* Nur 72 MHz statt 100 MHz Taktfrequenz&lt;br /&gt;
&#039;&#039;&#039;Vorteile gegenüber anderen &amp;quot;Kleinen&amp;quot; wie z.B. PIC, Atmel usw.&#039;&#039;&#039;&lt;br /&gt;
* nahezu gleicher Preis bei Hobby Anwendungen&lt;br /&gt;
* 32 Bit ohne Umwege in Assembler rechenbar&lt;br /&gt;
* bessere Peripherie&lt;br /&gt;
* ... und weitere 1000 Punkte ...&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Nachteil für Hoppy-Anwender&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Nicht direkt &amp;quot;Steckbrettauglich&amp;quot;, da kein DIL Gehäuse verfügbar. Der ebay-Shop dipmicro führt jedoch sehr günstige Lötadapter für Umsetzung von LQFP48 auf DIP48.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Software/Programmierung: ==&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
Als Programmieroberfläche kann eine kostenlose Struktur verwendet werden (wie meinen?):&lt;br /&gt;
&lt;br /&gt;
* Eclipse&lt;br /&gt;
* Coudesourcery Light&lt;br /&gt;
* OpenOCD&lt;br /&gt;
* Yagarto Tools&lt;br /&gt;
* Eclipse Plugin &amp;quot;GDB Hardware Debugging&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Folgende Umgebungen sind als Demoversion (32k Codesize) verfügbar, idR sind dutzende von Examples dabei:&lt;br /&gt;
&lt;br /&gt;
* Keil µVision (www.keil.com)&lt;br /&gt;
* IAR (www.iar.com)&lt;br /&gt;
&lt;br /&gt;
Programmieradapter&lt;br /&gt;
* J-Link / J-Trace Cortex-M3  (www.segger.com), als NonComercial für ca. 60,- zu haben, läuft in µVision, IAR, gdb&lt;br /&gt;
* z.B. OpenOCD ARM-USB-OCD (nicht kostenlos)&lt;br /&gt;
* Keil ULINK2, ULINK pro&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Installation für STM32 ===&lt;br /&gt;
&lt;br /&gt;
* Eclipse &amp;quot;Galileo&amp;quot; installation:&lt;br /&gt;
    http://www.eclipse.org/ &amp;gt;&amp;gt; Downloads &amp;gt;&amp;gt; &amp;quot;Eclipse IDE for C/C++ Developers (79 MB)&amp;quot;&lt;br /&gt;
    http://www.eclipse.org/downloads/download.php?file=/technology/epp/downloads/release/galileo/SR1/eclipse-cpp-galileo-SR1-win32.zip&lt;br /&gt;
    Entpacken der Datei eclipse-cpp-galileo-SR1-win32.zip nach &amp;quot;C:\WinARM\&amp;quot; (Ordner neu erstellen)&lt;br /&gt;
&lt;br /&gt;
* Yagarto Tools:&lt;br /&gt;
    http://www.yagarto.de/ &amp;gt;&amp;gt; &amp;quot;Download (for Windows)&amp;quot; &amp;gt;&amp;gt; &amp;quot;YAGARTO Tools&amp;quot;&lt;br /&gt;
    http://www.yagarto.de/download/yagarto/yagarto-tools-20091223-setup.exe&lt;br /&gt;
    Installieren, Auswahl Verzeichnis &amp;quot;C:\WinARM\yagarto-tools&amp;quot;&lt;br /&gt;
&lt;br /&gt;
* CodeSourcery:&lt;br /&gt;
    http://www.codesourcery.com/ &amp;gt;&amp;gt; Products&amp;gt;Sourcery G++&amp;gt;Editions&amp;gt;Lite &amp;gt;&amp;gt; Try Now&lt;br /&gt;
    http://www.codesourcery.com/downloads/public/public/gnu_toolchain/arm-none-eabi/arm-2009q3-68-arm-none-eabi.exe&lt;br /&gt;
    Installieren, Auswahl Verzeichnis &amp;quot;C:\WinARM\CodeSourcery&amp;quot;&lt;br /&gt;
&lt;br /&gt;
* OpenOCD, kompilliert von Martin-Thomas:&lt;br /&gt;
    http://www.siwawi.arubi.uni-kl.de/avr_projects/arm_projects/winarmtests/&lt;br /&gt;
    Die letzte Version ist &amp;quot;dont_download_this_OpenOCD_package_V0_3_1_mthomas.zip&amp;quot;&lt;br /&gt;
    Die aktuellste ist im Sourceforge als Quelldateien.&lt;br /&gt;
&lt;br /&gt;
* ST Firmware:&lt;br /&gt;
    http://www.st.com &amp;gt;&amp;gt; Auswahl CPU STM32F103xxx &amp;gt;&amp;gt; &amp;quot;Firmware&amp;quot; &amp;quot;STM32F10x_StdPeriph_Lib&amp;quot;&lt;br /&gt;
    http://www.st.com/mcu/devicedocs-STM32F103RC-110.html&lt;br /&gt;
    In dem ZIP ist ein ZIP mit der Firmware &amp;quot;\Archive\um0427.zip&amp;quot;&lt;br /&gt;
    Das ZIP &amp;quot;stm32f10x_stdperiph_lib.zip&amp;quot; Entpacken nach &amp;quot;C:\WinARM\examples\stm32_FW3.2.0\&lt;br /&gt;
&lt;br /&gt;
Eclipse:&lt;br /&gt;
Help &amp;gt;&amp;gt; Install New Software... &amp;gt;&amp;gt; http://download.eclipse.org/tools/cdt/releases/galileo&lt;br /&gt;
    &amp;quot;Eclipse C/C++ Development Tools&amp;quot; + &amp;quot;Eclipse C/C++ GDB Hardware Debugging&amp;quot; installieren&lt;br /&gt;
&lt;br /&gt;
=== Installation für STM32 auf einem zweiten Rechner (Eclipse/GCC Installation):===&lt;br /&gt;
* Kopieren des Verzeichnisses C:\WinARM\&lt;br /&gt;
* Die PATH-Variable in der Systemsteuerung mit den C:\WinARM.... Verzeichnissen nachführen&lt;br /&gt;
* Fertig.&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Demo-Projekte: ==&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
Martin Thomas hat ein umfangreiches Projekt erstellt, in der die Eclipse Einstellungen enthalten sind:&lt;br /&gt;
&lt;br /&gt;
&amp;quot;ChaN&#039;s FAT-Module with STM32 SPI&amp;quot;&lt;br /&gt;
http://www.siwawi.arubi.uni-kl.de/avr_projects/arm_projects/arm_memcards/index.html&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
== Errata, Tipps und Tricks ==&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
* AD-Wandler PA0: Im Errata steht, dass hier Fehler in der Wandlung entstehen könnten, also einen anderen Pin verwenden.&lt;br /&gt;
* CAN-Bus PD0/PD1: Remap geht erst ab der 100-Pin-Version. Steht im RM0008 unter 7.3.3. Alle Infos von RM0008 7.3.x sind interssant&lt;br /&gt;
&lt;br /&gt;
== Bezugsquellen ==&lt;br /&gt;
&lt;br /&gt;
=== Controller ===&lt;br /&gt;
Versandhäuser für Privatpersonen:&lt;br /&gt;
* Budelmann Elektronik: http://www.budelmann-elektronik.com (beispielsweise STM32F103RET6 9,00€/Stück, aufgelötet auf SMD-Adapterplatine 12,00€/Stück, momentan nur Anfrage über Kontaktformular möglich)&lt;br /&gt;
* Darisus: http://darisusgmbh.de/shop/index.php?cat=c2692_ARM-Cortex.html&lt;br /&gt;
* Sander: http://www.sander-electronic.de/be00069.html&lt;br /&gt;
* TME.eu: http://www.tme.eu/de/katalog/index.phtml#cleanParameters%3D1%26search%3DSTM32F10%26bf_szukaj%3D+&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Gewerblich liefern natürlich viele wie Farnell, Digikey usw..&lt;br /&gt;
&lt;br /&gt;
=== Evaluation-Boards ===&lt;br /&gt;
* http://shop.embedded-projects.net/index.php?module=artikel&amp;amp;action=gruppe&amp;amp;id=14&lt;br /&gt;
* http://www.watterott.com/de/Boards-Kits/ARM/ARM-Cortex-M3&lt;br /&gt;
* http://www.sander-electronic.de/es0028.html&lt;br /&gt;
* http://www.mikrocontroller.net/articles/MP32F103-Stick:_Ein_Mini-Mikrocontroller-Board_mit_USB_und_bis_zu_4MB_Datenspeicher&lt;br /&gt;
* http://www.futurlec.com/STM32_Development_Board.shtml&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Links, Foren, Communities ==&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
* Natürlich hier: http://www.mikrocontroller.net/forum/mikrocontroller-elektronik?filter=ARM*+STM32*+Cortex*&lt;br /&gt;
* https://my.st.com/public/STe2ecommunities/mcu/Lists/ARM%20CortexM3%20STM32/AllItems.aspx&lt;br /&gt;
* http://www.stm32circle.com/hom/index.php&lt;/div&gt;</summary>
		<author><name>80.72.130.218</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=STM32&amp;diff=45893</id>
		<title>STM32</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=STM32&amp;diff=45893"/>
		<updated>2010-04-08T08:50:53Z</updated>

		<summary type="html">&lt;p&gt;80.72.130.218: /* Evaluation-Boards */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;&lt;br /&gt;
== STM32 ==&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Der STM32 ist ein Mikrocontroller von ST ([www.st.com]http://www.st.com/mcu/inchtml-pages-stm32.html) mit einer 32-Bit ARM Cortex-M3 CPU. (http://www.arm.com/products/processors/cortex-m/index.php). Diese Architektur ist speziell für den Einsatz in Microcontrollern neu entwickelt, und löst damit die bisherigen ARM7 basierten Controller weitestgehend ab.&lt;br /&gt;
Den STM32 gibt es von ST in unzähligen Varianten mit variabler Peripherie und verschiedenen Gehäusegrössen und -formen. &lt;br /&gt;
Durch u.a. die geringe benötigte Chipfläche des Core ist es ST möglich, eine 32 Bit-CPU für weniger als 1 EUR an zu bieten.&lt;br /&gt;
* Cortex-M3 Kern&lt;br /&gt;
* 16KB ... 1MB Flash-ROM und bis zu 64KB SRAM&lt;br /&gt;
* Gehäuse 36 ... 144 Pins als QFN, LQFP und BGA&lt;br /&gt;
* Derzeit bis 72MHz, Modelle bis 120MHz sind angekündigt&lt;br /&gt;
* Externes Businterface&lt;br /&gt;
* Spannungsbereich 2,0 ... 3,6V&lt;br /&gt;
* Bis zu 112 IOs, viele davon 5V-tolerant&lt;br /&gt;
* Interner kalibrierter RC-Oszillator mit 8MHz&lt;br /&gt;
* Externer Quarz&lt;br /&gt;
* Real-Time-Clock mit eigenem Quarz und separater Stromversorgung&lt;br /&gt;
* Bis zu 11 Timer, je Timer bis zu 4 IC/OC/PWM Ausgänge. Davon 2x Motion Control Timer&lt;br /&gt;
* Systick Counter&lt;br /&gt;
* Bis zu 3 12-Bit AD-Wandler mit insgesamt 16 AD-Eingängen&lt;br /&gt;
* Bis zu 2 DMA Controller mit jeweils bis zu 12 Kanälen&lt;br /&gt;
* JTAG und SWD (Single Wire Debug) Interface&lt;br /&gt;
* Bis zu 2x I²C&lt;br /&gt;
* Bis zu 5x USART mit LIN, IrDA und Modem Control&lt;br /&gt;
* Bis zu 2x CAN&lt;br /&gt;
* USB 2.0 Full Speed&lt;br /&gt;
* SDIO Interface (z.B. SD-Card Reader)&lt;br /&gt;
* Ethernet&lt;br /&gt;
* ... (Siehe Datenblätter)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Struktur der Dokumentation: ==&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Als Beispiel der Dokumentation zeige ich mal stellvertretend den STM32F103RC. Die Seite von ST: http://www.st.com/mcu/devicedocs-STM32F103RC-110.html&lt;br /&gt;
Beinhaltet alle nötigen Informationen/Dateien/Dokumente passend zu diesem Prozessor.&lt;br /&gt;
&lt;br /&gt;
Diese Dokumente von ST beschreiben den Controller:&lt;br /&gt;
&lt;br /&gt;
* Datasheet &amp;quot;STM32F103xC/D/E&amp;quot; oder einer anderen Modellreihe&lt;br /&gt;
* Reference Manual &amp;quot;RM0008&amp;quot;&lt;br /&gt;
* Cortex-M3 Programming Manual &amp;quot;PM0056&amp;quot;&lt;br /&gt;
* Flash Programming Reference &amp;quot;PM0042&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Im Datasheet sind die speziellen Eigenschaften eines bestimmten Modells bzw. einer Modellreihe beschrieben und die exakten Daten und Pinouts aufgeführt. Die Peripheriemodule werden nur aufgeführt, nicht detailliert beschrieben. In der Referenz ist der gesamte Controller mit Peripheriemodulen im Detail beschrieben, gültig für alle STM32 Prozessoren. Details zum Prozessor selbst und den nicht STM32-spezifischen mit dem Cortex-M3 Core assoziierten Modulen wie dem Interrupt-Controller und dem Systick-Timer findet man jedoch nicht dort, sondern im Cortex-M3 Manual. Wer nicht die ST Firmware-Library verwendet, der benötigt zusätzlich das Flash Programming Manual für die Betriebsart des Flash-ROMs, d.h. die frequenzabhängige Konfiguration der Waitstates.&lt;br /&gt;
&lt;br /&gt;
Hinzu kommen optionale Dokumente von ARM, die den Cortex-M3 Kern beschreiben.&lt;br /&gt;
Siehe z.B. hier: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.set.cortexm/index.html. Hier gibt es den Opcode wenn man ihn in Assembler programmieren möchte: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0406b/index.html&lt;br /&gt;
&lt;br /&gt;
Zusätzlich sollten auch die Errata Sheets beachtet werden.&lt;br /&gt;
&lt;br /&gt;
Empfohlen sei auch die Appnote: &amp;quot;STM32F10xxx hardware development: getting started&amp;quot; http://www.st.com/stonline/products/literature/an/13675.pdf&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== FW-Lib: ==&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
ST bietet eine umfangreiche FW-LIB Bibliothek. Es ist eine einzige Bibliothek für alle STM32 Derivate. Das ist der große Vorteil von ST. Einmal programmieren und in allen STM32 verwendbar. Alle Funktionen sind gekapselt in einfache Strukturen und Funktionsaufrufe. Somit muss man sich nicht selbst um die Peripherieregister kümmern.&lt;br /&gt;
Die FW-Lib kann ebenfalls von der STM32 Seite kostenlos geladen werden:&lt;br /&gt;
&lt;br /&gt;
* Firmware &amp;quot;STM32F10x_StdPeriph_Lib&amp;quot;&lt;br /&gt;
&lt;br /&gt;
In dem Archiv ist die FW-LIB, zu jeder Peripherie gibt es bis zu 12 Demos und eine Beschreibung als CHM Datei &amp;quot;stm32f10x_stdperiph_lib_um.chm&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== CMSIS: ==&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Parallel zur Firmware-Library gibt es für die &amp;quot;Selbermacher&amp;quot; die CMSIS, die einen Teil der HW und den Core Support abdeckt.&lt;br /&gt;
Im Rahmen des CMSIS Standard (www.onARM.com) wurden die Headerfiles standardisiert, der Zugriff auf die Register erfolgt per &#039;&#039;&#039;Peripheral-&amp;gt;Register&#039;&#039;&#039;. Weiterhin existieren eine Zahl von Helferfunktionen für den NVIC, als auch eine SystemInit - Funktion, welche sich um die PLL kümmert.&lt;br /&gt;
&lt;br /&gt;
== Debug-Interface: ==&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
Als Debug Interface stehen zwei Varianten zur Auswahl:&lt;br /&gt;
* JTAG&lt;br /&gt;
* SWD (Single Wire Debug)&lt;br /&gt;
&lt;br /&gt;
Für JTAG sind 6 Steuerleitungen nötig, für SWD 2 (zzgl GND/3,3V).&lt;br /&gt;
Das SWD Interface verfügt ausserdem über eine weitere Leitung, SWO. Über diesen Kanal kann ein vereinfachtes Trace des Core ermöglicht, sowie printf-like Daten über den ITM Channel 0 geschickt und im Debugger ausgegeben werden.&lt;br /&gt;
&lt;br /&gt;
Die Coresight-Debug-Architektur ermöglicht ein non-invasive debugging, d.h. es können während des Betriebes ohne Beeinflussung des Prozessors Daten vom Speicher gelesen und in selbigen geschrieben werden.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Der 10-Polige JTAG-Stecker:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Ich habe einen 10 Poligen Debug-Stecker entworfen, der alle Varianten sowie einen UART Anschluss enthält:&lt;br /&gt;
&lt;br /&gt;
[[bild:jtag-debug-port10.png]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Die Funktionen:&#039;&#039;&#039;&lt;br /&gt;
* JTAG&lt;br /&gt;
* SWD&lt;br /&gt;
* Debug-UART-Anschluss (verbunden mit einem freien UART vom STM32) (alternativ ein MAX232 Chip dazwischen schalten)&lt;br /&gt;
* Weniger Platzbedarf auf der Platine (Standard-JTAG 20 Polig)&lt;br /&gt;
* Über 4-Poligen Würfel kann der UART benutzt werden (Pin 7/8/9/10)&lt;br /&gt;
* Es kann ein Jumper gesteckt werden für eine Option (Pin 7/8) ohne dass es sich mit dem RS232 Chip beißt (sofern er eingebaut wurde)&lt;br /&gt;
* Über einen 5-Poligen einreihigen Stecker kann SWD (SingleWireDebug) verwendet werden (Pin 1/3/5/7/9)&lt;br /&gt;
* den ganzen Stecker braucht es nur, wenn man den herkömlichen JTAG nutzen möchte.&lt;br /&gt;
* Kurzschlussschutz, da GND und +3V3 nicht gegenüber liegen&lt;br /&gt;
&lt;br /&gt;
In all meinen Projekten verwende ich nur noch diese Anordnung, denn sie ist einfach praktisch. Alles drauf und die Pins sind perfekt angeordnet für jede Art der Anwendung.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Vorteile: ==&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&#039;&#039;&#039;Vorteile gegenüber ARM7:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Interrupt-Controller jetzt Teil des Prozessors (als Core Peripheral), die Vector Table ist jetzt eine echte Vector Tabelle (keine jmps o.ä. wie bei ARM7). Durch automatismen zwischen Core und NVIC (auto register save r0..r3, lr, sp, pc) bei Interrupt Entry wird eine deutlich schnellere Ausführungszeit bei Interrupts erreicht. Der Interrupt Code muss sich nicht mehr selbst um die Sicherung der o.g. Register kümmern. Sind vor Beendigung einer ISR (d.h. Rücksprung zum User Code) weitere Interrupts pending, so werden diese ausgeführt, ohne dass eine komplette pop-push-sequenz der Register notwendig ist.&lt;br /&gt;
* Thumb-2 Befehlssatz wird schneller ausgeführt&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Vorteile gegenüber LPC1700 und LPC1300:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Flexiblere Gehäuseformen mit mehr Peripherie bei kleinen Gehäusen&lt;br /&gt;
* Genauerer ADC, insbesondere gegenüber LPC1300&lt;br /&gt;
* Flexiblere Varianten der Peripherie &amp;gt;&amp;gt; bei weniger einen deutlichen Preisvorteil&lt;br /&gt;
* ab 0,85 EUR (Stand 2010)&lt;br /&gt;
&#039;&#039;&#039;Nachteil gegenüber LPC1700:&#039;&#039;&#039;&lt;br /&gt;
* Nur 72 MHz statt 100 MHz Taktfrequenz&lt;br /&gt;
&#039;&#039;&#039;Vorteile gegenüber anderen &amp;quot;Kleinen&amp;quot; wie z.B. PIC, Atmel usw.&#039;&#039;&#039;&lt;br /&gt;
* nahezu gleicher Preis bei Hobby Anwendungen&lt;br /&gt;
* 32 Bit ohne Umwege in Assembler rechenbar&lt;br /&gt;
* bessere Peripherie&lt;br /&gt;
* ... und weitere 1000 Punkte ...&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Nachteil für Hoppy-Anwender&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Nicht direkt &amp;quot;Steckbrettauglich&amp;quot;, da kein DIL Gehäuse verfügbar. Der ebay-Shop dipmicro führt jedoch sehr günstige Lötadapter für Umsetzung von LQFP48 auf DIP48.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Software/Programmierung: ==&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
Als Programmieroberfläche kann eine kostenlose Struktur verwendet werden (wie meinen?):&lt;br /&gt;
&lt;br /&gt;
* Eclipse&lt;br /&gt;
* Coudesourcery Light&lt;br /&gt;
* OpenOCD&lt;br /&gt;
* Yagarto Tools&lt;br /&gt;
* Eclipse Plugin &amp;quot;GDB Hardware Debugging&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Folgende Umgebungen sind als Demoversion (32k Codesize) verfügbar, idR sind dutzende von Examples dabei:&lt;br /&gt;
&lt;br /&gt;
* Keil µVision (www.keil.com)&lt;br /&gt;
* IAR (www.iar.com)&lt;br /&gt;
&lt;br /&gt;
Programmieradapter&lt;br /&gt;
* J-Link / J-Trace Cortex-M3  (www.segger.com), als NonComercial für ca. 60,- zu haben, läuft in µVision, IAR, gdb&lt;br /&gt;
* z.B. OpenOCD ARM-USB-OCD (nicht kostenlos)&lt;br /&gt;
* Keil ULINK2, ULINK pro&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Installation für STM32&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Eclipse &amp;quot;Galileo&amp;quot; installation:&lt;br /&gt;
    http://www.eclipse.org/ &amp;gt;&amp;gt; Downloads &amp;gt;&amp;gt; &amp;quot;Eclipse IDE for C/C++ Developers (79 MB)&amp;quot;&lt;br /&gt;
    http://www.eclipse.org/downloads/download.php?file=/technology/epp/downloads/release/galileo/SR1/eclipse-cpp-galileo-SR1-win32.zip&lt;br /&gt;
    Entpacken der Datei eclipse-cpp-galileo-SR1-win32.zip nach &amp;quot;C:\WinARM\&amp;quot; (Ordner neu erstellen)&lt;br /&gt;
&lt;br /&gt;
* Yagarto Tools:&lt;br /&gt;
    http://www.yagarto.de/ &amp;gt;&amp;gt; &amp;quot;Download (for Windows)&amp;quot; &amp;gt;&amp;gt; &amp;quot;YAGARTO Tools&amp;quot;&lt;br /&gt;
    http://www.yagarto.de/download/yagarto/yagarto-tools-20091223-setup.exe&lt;br /&gt;
    Installieren, Auswahl Verzeichnis &amp;quot;C:\WinARM\yagarto-tools&amp;quot;&lt;br /&gt;
&lt;br /&gt;
* CodeSourcery:&lt;br /&gt;
    http://www.codesourcery.com/ &amp;gt;&amp;gt; Products&amp;gt;Sourcery G++&amp;gt;Editions&amp;gt;Lite &amp;gt;&amp;gt; Try Now&lt;br /&gt;
    http://www.codesourcery.com/downloads/public/public/gnu_toolchain/arm-none-eabi/arm-2009q3-68-arm-none-eabi.exe&lt;br /&gt;
    Installieren, Auswahl Verzeichnis &amp;quot;C:\WinARM\CodeSourcery&amp;quot;&lt;br /&gt;
&lt;br /&gt;
* OpenOCD, kompilliert von Martin-Thomas:&lt;br /&gt;
    http://www.siwawi.arubi.uni-kl.de/avr_projects/arm_projects/winarmtests/&lt;br /&gt;
    Die letzte Version ist &amp;quot;dont_download_this_OpenOCD_package_V0_3_1_mthomas.zip&amp;quot;&lt;br /&gt;
    Die aktuellste ist im Sourceforge als Quelldateien.&lt;br /&gt;
&lt;br /&gt;
* ST Firmware:&lt;br /&gt;
    http://www.st.com &amp;gt;&amp;gt; Auswahl CPU STM32F103xxx &amp;gt;&amp;gt; &amp;quot;Firmware&amp;quot; &amp;quot;STM32F10x_StdPeriph_Lib&amp;quot;&lt;br /&gt;
    http://www.st.com/mcu/devicedocs-STM32F103RC-110.html&lt;br /&gt;
    In dem ZIP ist ein ZIP mit der Firmware &amp;quot;\Archive\um0427.zip&amp;quot;&lt;br /&gt;
    Das ZIP &amp;quot;stm32f10x_stdperiph_lib.zip&amp;quot; Entpacken nach &amp;quot;C:\WinARM\examples\stm32_FW3.2.0\&lt;br /&gt;
&lt;br /&gt;
Eclipse:&lt;br /&gt;
Help &amp;gt;&amp;gt; Install New Software... &amp;gt;&amp;gt; http://download.eclipse.org/tools/cdt/releases/galileo&lt;br /&gt;
    &amp;quot;Eclipse C/C++ Development Tools&amp;quot; + &amp;quot;Eclipse C/C++ GDB Hardware Debugging&amp;quot; installieren&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Installation für STM32 auf einem zweiten Rechner (Eclipse/GCC Installation):&#039;&#039;&#039;&lt;br /&gt;
* Kopieren des Verzeichnisses C:\WinARM\&lt;br /&gt;
* Die PATH-Variable in der Systemsteuerung mit den C:\WinARM.... Verzeichnissen nachführen&lt;br /&gt;
* Fertig.&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Demo-Projekte: ==&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
Martin Thomas hat ein umfangreiches Projekt erstellt, in der die Eclipse Einstellungen enthalten sind:&lt;br /&gt;
&lt;br /&gt;
&amp;quot;ChaN&#039;s FAT-Module with STM32 SPI&amp;quot;&lt;br /&gt;
http://www.siwawi.arubi.uni-kl.de/avr_projects/arm_projects/arm_memcards/index.html&lt;br /&gt;
&lt;br /&gt;
== Bezugsquellen ==&lt;br /&gt;
&lt;br /&gt;
=== Controller ===&lt;br /&gt;
Versandhäuser für Privatpersonen:&lt;br /&gt;
* TME.eu: http://www.tme.eu/de/katalog/index.phtml#cleanParameters%3D1%26search%3DSTM32F10%26bf_szukaj%3D+&lt;br /&gt;
* Darisus: http://darisusgmbh.de/shop/index.php?cat=c2692_ARM-Cortex.html&lt;br /&gt;
* Sander: http://www.sander-electronic.de/be00069.html&lt;br /&gt;
&lt;br /&gt;
Gewerblich liefern natürlich viele wie Farnell, Digikey usw..&lt;br /&gt;
&lt;br /&gt;
=== Evaluation-Boards ===&lt;br /&gt;
* http://shop.embedded-projects.net/index.php?module=artikel&amp;amp;action=gruppe&amp;amp;id=14&lt;br /&gt;
* http://www.watterott.com/de/Boards-Kits/ARM/ARM-Cortex-M3&lt;br /&gt;
* http://www.sander-electronic.de/es0028.html&lt;br /&gt;
* http://www.mikrocontroller.net/articles/MP32F103-Stick:_Ein_Mini-Mikrocontroller-Board_mit_USB_und_bis_zu_4MB_Datenspeicher&lt;/div&gt;</summary>
		<author><name>80.72.130.218</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=STM32&amp;diff=45892</id>
		<title>STM32</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=STM32&amp;diff=45892"/>
		<updated>2010-04-08T08:48:55Z</updated>

		<summary type="html">&lt;p&gt;80.72.130.218: /* Bezugsquellen */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;&lt;br /&gt;
== STM32 ==&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Der STM32 ist ein Mikrocontroller von ST ([www.st.com]http://www.st.com/mcu/inchtml-pages-stm32.html) mit einer 32-Bit ARM Cortex-M3 CPU. (http://www.arm.com/products/processors/cortex-m/index.php). Diese Architektur ist speziell für den Einsatz in Microcontrollern neu entwickelt, und löst damit die bisherigen ARM7 basierten Controller weitestgehend ab.&lt;br /&gt;
Den STM32 gibt es von ST in unzähligen Varianten mit variabler Peripherie und verschiedenen Gehäusegrössen und -formen. &lt;br /&gt;
Durch u.a. die geringe benötigte Chipfläche des Core ist es ST möglich, eine 32 Bit-CPU für weniger als 1 EUR an zu bieten.&lt;br /&gt;
* Cortex-M3 Kern&lt;br /&gt;
* 16KB ... 1MB Flash-ROM und bis zu 64KB SRAM&lt;br /&gt;
* Gehäuse 36 ... 144 Pins als QFN, LQFP und BGA&lt;br /&gt;
* Derzeit bis 72MHz, Modelle bis 120MHz sind angekündigt&lt;br /&gt;
* Externes Businterface&lt;br /&gt;
* Spannungsbereich 2,0 ... 3,6V&lt;br /&gt;
* Bis zu 112 IOs, viele davon 5V-tolerant&lt;br /&gt;
* Interner kalibrierter RC-Oszillator mit 8MHz&lt;br /&gt;
* Externer Quarz&lt;br /&gt;
* Real-Time-Clock mit eigenem Quarz und separater Stromversorgung&lt;br /&gt;
* Bis zu 11 Timer, je Timer bis zu 4 IC/OC/PWM Ausgänge. Davon 2x Motion Control Timer&lt;br /&gt;
* Systick Counter&lt;br /&gt;
* Bis zu 3 12-Bit AD-Wandler mit insgesamt 16 AD-Eingängen&lt;br /&gt;
* Bis zu 2 DMA Controller mit jeweils bis zu 12 Kanälen&lt;br /&gt;
* JTAG und SWD (Single Wire Debug) Interface&lt;br /&gt;
* Bis zu 2x I²C&lt;br /&gt;
* Bis zu 5x USART mit LIN, IrDA und Modem Control&lt;br /&gt;
* Bis zu 2x CAN&lt;br /&gt;
* USB 2.0 Full Speed&lt;br /&gt;
* SDIO Interface (z.B. SD-Card Reader)&lt;br /&gt;
* Ethernet&lt;br /&gt;
* ... (Siehe Datenblätter)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Struktur der Dokumentation: ==&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Als Beispiel der Dokumentation zeige ich mal stellvertretend den STM32F103RC. Die Seite von ST: http://www.st.com/mcu/devicedocs-STM32F103RC-110.html&lt;br /&gt;
Beinhaltet alle nötigen Informationen/Dateien/Dokumente passend zu diesem Prozessor.&lt;br /&gt;
&lt;br /&gt;
Diese Dokumente von ST beschreiben den Controller:&lt;br /&gt;
&lt;br /&gt;
* Datasheet &amp;quot;STM32F103xC/D/E&amp;quot; oder einer anderen Modellreihe&lt;br /&gt;
* Reference Manual &amp;quot;RM0008&amp;quot;&lt;br /&gt;
* Cortex-M3 Programming Manual &amp;quot;PM0056&amp;quot;&lt;br /&gt;
* Flash Programming Reference &amp;quot;PM0042&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Im Datasheet sind die speziellen Eigenschaften eines bestimmten Modells bzw. einer Modellreihe beschrieben und die exakten Daten und Pinouts aufgeführt. Die Peripheriemodule werden nur aufgeführt, nicht detailliert beschrieben. In der Referenz ist der gesamte Controller mit Peripheriemodulen im Detail beschrieben, gültig für alle STM32 Prozessoren. Details zum Prozessor selbst und den nicht STM32-spezifischen mit dem Cortex-M3 Core assoziierten Modulen wie dem Interrupt-Controller und dem Systick-Timer findet man jedoch nicht dort, sondern im Cortex-M3 Manual. Wer nicht die ST Firmware-Library verwendet, der benötigt zusätzlich das Flash Programming Manual für die Betriebsart des Flash-ROMs, d.h. die frequenzabhängige Konfiguration der Waitstates.&lt;br /&gt;
&lt;br /&gt;
Hinzu kommen optionale Dokumente von ARM, die den Cortex-M3 Kern beschreiben.&lt;br /&gt;
Siehe z.B. hier: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.set.cortexm/index.html. Hier gibt es den Opcode wenn man ihn in Assembler programmieren möchte: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0406b/index.html&lt;br /&gt;
&lt;br /&gt;
Zusätzlich sollten auch die Errata Sheets beachtet werden.&lt;br /&gt;
&lt;br /&gt;
Empfohlen sei auch die Appnote: &amp;quot;STM32F10xxx hardware development: getting started&amp;quot; http://www.st.com/stonline/products/literature/an/13675.pdf&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== FW-Lib: ==&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
ST bietet eine umfangreiche FW-LIB Bibliothek. Es ist eine einzige Bibliothek für alle STM32 Derivate. Das ist der große Vorteil von ST. Einmal programmieren und in allen STM32 verwendbar. Alle Funktionen sind gekapselt in einfache Strukturen und Funktionsaufrufe. Somit muss man sich nicht selbst um die Peripherieregister kümmern.&lt;br /&gt;
Die FW-Lib kann ebenfalls von der STM32 Seite kostenlos geladen werden:&lt;br /&gt;
&lt;br /&gt;
* Firmware &amp;quot;STM32F10x_StdPeriph_Lib&amp;quot;&lt;br /&gt;
&lt;br /&gt;
In dem Archiv ist die FW-LIB, zu jeder Peripherie gibt es bis zu 12 Demos und eine Beschreibung als CHM Datei &amp;quot;stm32f10x_stdperiph_lib_um.chm&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== CMSIS: ==&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Parallel zur Firmware-Library gibt es für die &amp;quot;Selbermacher&amp;quot; die CMSIS, die einen Teil der HW und den Core Support abdeckt.&lt;br /&gt;
Im Rahmen des CMSIS Standard (www.onARM.com) wurden die Headerfiles standardisiert, der Zugriff auf die Register erfolgt per &#039;&#039;&#039;Peripheral-&amp;gt;Register&#039;&#039;&#039;. Weiterhin existieren eine Zahl von Helferfunktionen für den NVIC, als auch eine SystemInit - Funktion, welche sich um die PLL kümmert.&lt;br /&gt;
&lt;br /&gt;
== Debug-Interface: ==&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
Als Debug Interface stehen zwei Varianten zur Auswahl:&lt;br /&gt;
* JTAG&lt;br /&gt;
* SWD (Single Wire Debug)&lt;br /&gt;
&lt;br /&gt;
Für JTAG sind 6 Steuerleitungen nötig, für SWD 2 (zzgl GND/3,3V).&lt;br /&gt;
Das SWD Interface verfügt ausserdem über eine weitere Leitung, SWO. Über diesen Kanal kann ein vereinfachtes Trace des Core ermöglicht, sowie printf-like Daten über den ITM Channel 0 geschickt und im Debugger ausgegeben werden.&lt;br /&gt;
&lt;br /&gt;
Die Coresight-Debug-Architektur ermöglicht ein non-invasive debugging, d.h. es können während des Betriebes ohne Beeinflussung des Prozessors Daten vom Speicher gelesen und in selbigen geschrieben werden.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Der 10-Polige JTAG-Stecker:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Ich habe einen 10 Poligen Debug-Stecker entworfen, der alle Varianten sowie einen UART Anschluss enthält:&lt;br /&gt;
&lt;br /&gt;
[[bild:jtag-debug-port10.png]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Die Funktionen:&#039;&#039;&#039;&lt;br /&gt;
* JTAG&lt;br /&gt;
* SWD&lt;br /&gt;
* Debug-UART-Anschluss (verbunden mit einem freien UART vom STM32) (alternativ ein MAX232 Chip dazwischen schalten)&lt;br /&gt;
* Weniger Platzbedarf auf der Platine (Standard-JTAG 20 Polig)&lt;br /&gt;
* Über 4-Poligen Würfel kann der UART benutzt werden (Pin 7/8/9/10)&lt;br /&gt;
* Es kann ein Jumper gesteckt werden für eine Option (Pin 7/8) ohne dass es sich mit dem RS232 Chip beißt (sofern er eingebaut wurde)&lt;br /&gt;
* Über einen 5-Poligen einreihigen Stecker kann SWD (SingleWireDebug) verwendet werden (Pin 1/3/5/7/9)&lt;br /&gt;
* den ganzen Stecker braucht es nur, wenn man den herkömlichen JTAG nutzen möchte.&lt;br /&gt;
* Kurzschlussschutz, da GND und +3V3 nicht gegenüber liegen&lt;br /&gt;
&lt;br /&gt;
In all meinen Projekten verwende ich nur noch diese Anordnung, denn sie ist einfach praktisch. Alles drauf und die Pins sind perfekt angeordnet für jede Art der Anwendung.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Vorteile: ==&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&#039;&#039;&#039;Vorteile gegenüber ARM7:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Interrupt-Controller jetzt Teil des Prozessors (als Core Peripheral), die Vector Table ist jetzt eine echte Vector Tabelle (keine jmps o.ä. wie bei ARM7). Durch automatismen zwischen Core und NVIC (auto register save r0..r3, lr, sp, pc) bei Interrupt Entry wird eine deutlich schnellere Ausführungszeit bei Interrupts erreicht. Der Interrupt Code muss sich nicht mehr selbst um die Sicherung der o.g. Register kümmern. Sind vor Beendigung einer ISR (d.h. Rücksprung zum User Code) weitere Interrupts pending, so werden diese ausgeführt, ohne dass eine komplette pop-push-sequenz der Register notwendig ist.&lt;br /&gt;
* Thumb-2 Befehlssatz wird schneller ausgeführt&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Vorteile gegenüber LPC1700 und LPC1300:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Flexiblere Gehäuseformen mit mehr Peripherie bei kleinen Gehäusen&lt;br /&gt;
* Genauerer ADC, insbesondere gegenüber LPC1300&lt;br /&gt;
* Flexiblere Varianten der Peripherie &amp;gt;&amp;gt; bei weniger einen deutlichen Preisvorteil&lt;br /&gt;
* ab 0,85 EUR (Stand 2010)&lt;br /&gt;
&#039;&#039;&#039;Nachteil gegenüber LPC1700:&#039;&#039;&#039;&lt;br /&gt;
* Nur 72 MHz statt 100 MHz Taktfrequenz&lt;br /&gt;
&#039;&#039;&#039;Vorteile gegenüber anderen &amp;quot;Kleinen&amp;quot; wie z.B. PIC, Atmel usw.&#039;&#039;&#039;&lt;br /&gt;
* nahezu gleicher Preis bei Hobby Anwendungen&lt;br /&gt;
* 32 Bit ohne Umwege in Assembler rechenbar&lt;br /&gt;
* bessere Peripherie&lt;br /&gt;
* ... und weitere 1000 Punkte ...&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Nachteil für Hoppy-Anwender&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Nicht direkt &amp;quot;Steckbrettauglich&amp;quot;, da kein DIL Gehäuse verfügbar. Der ebay-Shop dipmicro führt jedoch sehr günstige Lötadapter für Umsetzung von LQFP48 auf DIP48.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Software/Programmierung: ==&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
Als Programmieroberfläche kann eine kostenlose Struktur verwendet werden (wie meinen?):&lt;br /&gt;
&lt;br /&gt;
* Eclipse&lt;br /&gt;
* Coudesourcery Light&lt;br /&gt;
* OpenOCD&lt;br /&gt;
* Yagarto Tools&lt;br /&gt;
* Eclipse Plugin &amp;quot;GDB Hardware Debugging&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Folgende Umgebungen sind als Demoversion (32k Codesize) verfügbar, idR sind dutzende von Examples dabei:&lt;br /&gt;
&lt;br /&gt;
* Keil µVision (www.keil.com)&lt;br /&gt;
* IAR (www.iar.com)&lt;br /&gt;
&lt;br /&gt;
Programmieradapter&lt;br /&gt;
* J-Link / J-Trace Cortex-M3  (www.segger.com), als NonComercial für ca. 60,- zu haben, läuft in µVision, IAR, gdb&lt;br /&gt;
* z.B. OpenOCD ARM-USB-OCD (nicht kostenlos)&lt;br /&gt;
* Keil ULINK2, ULINK pro&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Installation für STM32&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Eclipse &amp;quot;Galileo&amp;quot; installation:&lt;br /&gt;
    http://www.eclipse.org/ &amp;gt;&amp;gt; Downloads &amp;gt;&amp;gt; &amp;quot;Eclipse IDE for C/C++ Developers (79 MB)&amp;quot;&lt;br /&gt;
    http://www.eclipse.org/downloads/download.php?file=/technology/epp/downloads/release/galileo/SR1/eclipse-cpp-galileo-SR1-win32.zip&lt;br /&gt;
    Entpacken der Datei eclipse-cpp-galileo-SR1-win32.zip nach &amp;quot;C:\WinARM\&amp;quot; (Ordner neu erstellen)&lt;br /&gt;
&lt;br /&gt;
* Yagarto Tools:&lt;br /&gt;
    http://www.yagarto.de/ &amp;gt;&amp;gt; &amp;quot;Download (for Windows)&amp;quot; &amp;gt;&amp;gt; &amp;quot;YAGARTO Tools&amp;quot;&lt;br /&gt;
    http://www.yagarto.de/download/yagarto/yagarto-tools-20091223-setup.exe&lt;br /&gt;
    Installieren, Auswahl Verzeichnis &amp;quot;C:\WinARM\yagarto-tools&amp;quot;&lt;br /&gt;
&lt;br /&gt;
* CodeSourcery:&lt;br /&gt;
    http://www.codesourcery.com/ &amp;gt;&amp;gt; Products&amp;gt;Sourcery G++&amp;gt;Editions&amp;gt;Lite &amp;gt;&amp;gt; Try Now&lt;br /&gt;
    http://www.codesourcery.com/downloads/public/public/gnu_toolchain/arm-none-eabi/arm-2009q3-68-arm-none-eabi.exe&lt;br /&gt;
    Installieren, Auswahl Verzeichnis &amp;quot;C:\WinARM\CodeSourcery&amp;quot;&lt;br /&gt;
&lt;br /&gt;
* OpenOCD, kompilliert von Martin-Thomas:&lt;br /&gt;
    http://www.siwawi.arubi.uni-kl.de/avr_projects/arm_projects/winarmtests/&lt;br /&gt;
    Die letzte Version ist &amp;quot;dont_download_this_OpenOCD_package_V0_3_1_mthomas.zip&amp;quot;&lt;br /&gt;
    Die aktuellste ist im Sourceforge als Quelldateien.&lt;br /&gt;
&lt;br /&gt;
* ST Firmware:&lt;br /&gt;
    http://www.st.com &amp;gt;&amp;gt; Auswahl CPU STM32F103xxx &amp;gt;&amp;gt; &amp;quot;Firmware&amp;quot; &amp;quot;STM32F10x_StdPeriph_Lib&amp;quot;&lt;br /&gt;
    http://www.st.com/mcu/devicedocs-STM32F103RC-110.html&lt;br /&gt;
    In dem ZIP ist ein ZIP mit der Firmware &amp;quot;\Archive\um0427.zip&amp;quot;&lt;br /&gt;
    Das ZIP &amp;quot;stm32f10x_stdperiph_lib.zip&amp;quot; Entpacken nach &amp;quot;C:\WinARM\examples\stm32_FW3.2.0\&lt;br /&gt;
&lt;br /&gt;
Eclipse:&lt;br /&gt;
Help &amp;gt;&amp;gt; Install New Software... &amp;gt;&amp;gt; http://download.eclipse.org/tools/cdt/releases/galileo&lt;br /&gt;
    &amp;quot;Eclipse C/C++ Development Tools&amp;quot; + &amp;quot;Eclipse C/C++ GDB Hardware Debugging&amp;quot; installieren&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Installation für STM32 auf einem zweiten Rechner (Eclipse/GCC Installation):&#039;&#039;&#039;&lt;br /&gt;
* Kopieren des Verzeichnisses C:\WinARM\&lt;br /&gt;
* Die PATH-Variable in der Systemsteuerung mit den C:\WinARM.... Verzeichnissen nachführen&lt;br /&gt;
* Fertig.&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Demo-Projekte: ==&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
Martin Thomas hat ein umfangreiches Projekt erstellt, in der die Eclipse Einstellungen enthalten sind:&lt;br /&gt;
&lt;br /&gt;
&amp;quot;ChaN&#039;s FAT-Module with STM32 SPI&amp;quot;&lt;br /&gt;
http://www.siwawi.arubi.uni-kl.de/avr_projects/arm_projects/arm_memcards/index.html&lt;br /&gt;
&lt;br /&gt;
== Bezugsquellen ==&lt;br /&gt;
&lt;br /&gt;
=== Controller ===&lt;br /&gt;
Versandhäuser für Privatpersonen:&lt;br /&gt;
* TME.eu: http://www.tme.eu/de/katalog/index.phtml#cleanParameters%3D1%26search%3DSTM32F10%26bf_szukaj%3D+&lt;br /&gt;
* Darisus: http://darisusgmbh.de/shop/index.php?cat=c2692_ARM-Cortex.html&lt;br /&gt;
* Sander: http://www.sander-electronic.de/be00069.html&lt;br /&gt;
&lt;br /&gt;
Gewerblich liefern natürlich viele wie Farnell, Digikey usw..&lt;br /&gt;
&lt;br /&gt;
=== Evaluation-Boards ===&lt;br /&gt;
* http://shop.embedded-projects.net/index.php?module=artikel&amp;amp;action=gruppe&amp;amp;id=14&lt;br /&gt;
* http://www.watterott.com/de/Boards-Kits/ARM/ARM-Cortex-M3&lt;br /&gt;
* http://www.sander-electronic.de/es0028.html&lt;/div&gt;</summary>
		<author><name>80.72.130.218</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=STM32&amp;diff=45891</id>
		<title>STM32</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=STM32&amp;diff=45891"/>
		<updated>2010-04-08T08:47:13Z</updated>

		<summary type="html">&lt;p&gt;80.72.130.218: /* Evaluation-Boards: */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;&lt;br /&gt;
== STM32 ==&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Der STM32 ist ein Mikrocontroller von ST ([www.st.com]http://www.st.com/mcu/inchtml-pages-stm32.html) mit einer 32-Bit ARM Cortex-M3 CPU. (http://www.arm.com/products/processors/cortex-m/index.php). Diese Architektur ist speziell für den Einsatz in Microcontrollern neu entwickelt, und löst damit die bisherigen ARM7 basierten Controller weitestgehend ab.&lt;br /&gt;
Den STM32 gibt es von ST in unzähligen Varianten mit variabler Peripherie und verschiedenen Gehäusegrössen und -formen. &lt;br /&gt;
Durch u.a. die geringe benötigte Chipfläche des Core ist es ST möglich, eine 32 Bit-CPU für weniger als 1 EUR an zu bieten.&lt;br /&gt;
* Cortex-M3 Kern&lt;br /&gt;
* 16KB ... 1MB Flash-ROM und bis zu 64KB SRAM&lt;br /&gt;
* Gehäuse 36 ... 144 Pins als QFN, LQFP und BGA&lt;br /&gt;
* Derzeit bis 72MHz, Modelle bis 120MHz sind angekündigt&lt;br /&gt;
* Externes Businterface&lt;br /&gt;
* Spannungsbereich 2,0 ... 3,6V&lt;br /&gt;
* Bis zu 112 IOs, viele davon 5V-tolerant&lt;br /&gt;
* Interner kalibrierter RC-Oszillator mit 8MHz&lt;br /&gt;
* Externer Quarz&lt;br /&gt;
* Real-Time-Clock mit eigenem Quarz und separater Stromversorgung&lt;br /&gt;
* Bis zu 11 Timer, je Timer bis zu 4 IC/OC/PWM Ausgänge. Davon 2x Motion Control Timer&lt;br /&gt;
* Systick Counter&lt;br /&gt;
* Bis zu 3 12-Bit AD-Wandler mit insgesamt 16 AD-Eingängen&lt;br /&gt;
* Bis zu 2 DMA Controller mit jeweils bis zu 12 Kanälen&lt;br /&gt;
* JTAG und SWD (Single Wire Debug) Interface&lt;br /&gt;
* Bis zu 2x I²C&lt;br /&gt;
* Bis zu 5x USART mit LIN, IrDA und Modem Control&lt;br /&gt;
* Bis zu 2x CAN&lt;br /&gt;
* USB 2.0 Full Speed&lt;br /&gt;
* SDIO Interface (z.B. SD-Card Reader)&lt;br /&gt;
* Ethernet&lt;br /&gt;
* ... (Siehe Datenblätter)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Struktur der Dokumentation: ==&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Als Beispiel der Dokumentation zeige ich mal stellvertretend den STM32F103RC. Die Seite von ST: http://www.st.com/mcu/devicedocs-STM32F103RC-110.html&lt;br /&gt;
Beinhaltet alle nötigen Informationen/Dateien/Dokumente passend zu diesem Prozessor.&lt;br /&gt;
&lt;br /&gt;
Diese Dokumente von ST beschreiben den Controller:&lt;br /&gt;
&lt;br /&gt;
* Datasheet &amp;quot;STM32F103xC/D/E&amp;quot; oder einer anderen Modellreihe&lt;br /&gt;
* Reference Manual &amp;quot;RM0008&amp;quot;&lt;br /&gt;
* Cortex-M3 Programming Manual &amp;quot;PM0056&amp;quot;&lt;br /&gt;
* Flash Programming Reference &amp;quot;PM0042&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Im Datasheet sind die speziellen Eigenschaften eines bestimmten Modells bzw. einer Modellreihe beschrieben und die exakten Daten und Pinouts aufgeführt. Die Peripheriemodule werden nur aufgeführt, nicht detailliert beschrieben. In der Referenz ist der gesamte Controller mit Peripheriemodulen im Detail beschrieben, gültig für alle STM32 Prozessoren. Details zum Prozessor selbst und den nicht STM32-spezifischen mit dem Cortex-M3 Core assoziierten Modulen wie dem Interrupt-Controller und dem Systick-Timer findet man jedoch nicht dort, sondern im Cortex-M3 Manual. Wer nicht die ST Firmware-Library verwendet, der benötigt zusätzlich das Flash Programming Manual für die Betriebsart des Flash-ROMs, d.h. die frequenzabhängige Konfiguration der Waitstates.&lt;br /&gt;
&lt;br /&gt;
Hinzu kommen optionale Dokumente von ARM, die den Cortex-M3 Kern beschreiben.&lt;br /&gt;
Siehe z.B. hier: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.set.cortexm/index.html. Hier gibt es den Opcode wenn man ihn in Assembler programmieren möchte: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0406b/index.html&lt;br /&gt;
&lt;br /&gt;
Zusätzlich sollten auch die Errata Sheets beachtet werden.&lt;br /&gt;
&lt;br /&gt;
Empfohlen sei auch die Appnote: &amp;quot;STM32F10xxx hardware development: getting started&amp;quot; http://www.st.com/stonline/products/literature/an/13675.pdf&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== FW-Lib: ==&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
ST bietet eine umfangreiche FW-LIB Bibliothek. Es ist eine einzige Bibliothek für alle STM32 Derivate. Das ist der große Vorteil von ST. Einmal programmieren und in allen STM32 verwendbar. Alle Funktionen sind gekapselt in einfache Strukturen und Funktionsaufrufe. Somit muss man sich nicht selbst um die Peripherieregister kümmern.&lt;br /&gt;
Die FW-Lib kann ebenfalls von der STM32 Seite kostenlos geladen werden:&lt;br /&gt;
&lt;br /&gt;
* Firmware &amp;quot;STM32F10x_StdPeriph_Lib&amp;quot;&lt;br /&gt;
&lt;br /&gt;
In dem Archiv ist die FW-LIB, zu jeder Peripherie gibt es bis zu 12 Demos und eine Beschreibung als CHM Datei &amp;quot;stm32f10x_stdperiph_lib_um.chm&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== CMSIS: ==&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Parallel zur Firmware-Library gibt es für die &amp;quot;Selbermacher&amp;quot; die CMSIS, die einen Teil der HW und den Core Support abdeckt.&lt;br /&gt;
Im Rahmen des CMSIS Standard (www.onARM.com) wurden die Headerfiles standardisiert, der Zugriff auf die Register erfolgt per &#039;&#039;&#039;Peripheral-&amp;gt;Register&#039;&#039;&#039;. Weiterhin existieren eine Zahl von Helferfunktionen für den NVIC, als auch eine SystemInit - Funktion, welche sich um die PLL kümmert.&lt;br /&gt;
&lt;br /&gt;
== Debug-Interface: ==&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
Als Debug Interface stehen zwei Varianten zur Auswahl:&lt;br /&gt;
* JTAG&lt;br /&gt;
* SWD (Single Wire Debug)&lt;br /&gt;
&lt;br /&gt;
Für JTAG sind 6 Steuerleitungen nötig, für SWD 2 (zzgl GND/3,3V).&lt;br /&gt;
Das SWD Interface verfügt ausserdem über eine weitere Leitung, SWO. Über diesen Kanal kann ein vereinfachtes Trace des Core ermöglicht, sowie printf-like Daten über den ITM Channel 0 geschickt und im Debugger ausgegeben werden.&lt;br /&gt;
&lt;br /&gt;
Die Coresight-Debug-Architektur ermöglicht ein non-invasive debugging, d.h. es können während des Betriebes ohne Beeinflussung des Prozessors Daten vom Speicher gelesen und in selbigen geschrieben werden.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Der 10-Polige JTAG-Stecker:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Ich habe einen 10 Poligen Debug-Stecker entworfen, der alle Varianten sowie einen UART Anschluss enthält:&lt;br /&gt;
&lt;br /&gt;
[[bild:jtag-debug-port10.png]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Die Funktionen:&#039;&#039;&#039;&lt;br /&gt;
* JTAG&lt;br /&gt;
* SWD&lt;br /&gt;
* Debug-UART-Anschluss (verbunden mit einem freien UART vom STM32) (alternativ ein MAX232 Chip dazwischen schalten)&lt;br /&gt;
* Weniger Platzbedarf auf der Platine (Standard-JTAG 20 Polig)&lt;br /&gt;
* Über 4-Poligen Würfel kann der UART benutzt werden (Pin 7/8/9/10)&lt;br /&gt;
* Es kann ein Jumper gesteckt werden für eine Option (Pin 7/8) ohne dass es sich mit dem RS232 Chip beißt (sofern er eingebaut wurde)&lt;br /&gt;
* Über einen 5-Poligen einreihigen Stecker kann SWD (SingleWireDebug) verwendet werden (Pin 1/3/5/7/9)&lt;br /&gt;
* den ganzen Stecker braucht es nur, wenn man den herkömlichen JTAG nutzen möchte.&lt;br /&gt;
* Kurzschlussschutz, da GND und +3V3 nicht gegenüber liegen&lt;br /&gt;
&lt;br /&gt;
In all meinen Projekten verwende ich nur noch diese Anordnung, denn sie ist einfach praktisch. Alles drauf und die Pins sind perfekt angeordnet für jede Art der Anwendung.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Vorteile: ==&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&#039;&#039;&#039;Vorteile gegenüber ARM7:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Interrupt-Controller jetzt Teil des Prozessors (als Core Peripheral), die Vector Table ist jetzt eine echte Vector Tabelle (keine jmps o.ä. wie bei ARM7). Durch automatismen zwischen Core und NVIC (auto register save r0..r3, lr, sp, pc) bei Interrupt Entry wird eine deutlich schnellere Ausführungszeit bei Interrupts erreicht. Der Interrupt Code muss sich nicht mehr selbst um die Sicherung der o.g. Register kümmern. Sind vor Beendigung einer ISR (d.h. Rücksprung zum User Code) weitere Interrupts pending, so werden diese ausgeführt, ohne dass eine komplette pop-push-sequenz der Register notwendig ist.&lt;br /&gt;
* Thumb-2 Befehlssatz wird schneller ausgeführt&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Vorteile gegenüber LPC1700 und LPC1300:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Flexiblere Gehäuseformen mit mehr Peripherie bei kleinen Gehäusen&lt;br /&gt;
* Genauerer ADC, insbesondere gegenüber LPC1300&lt;br /&gt;
* Flexiblere Varianten der Peripherie &amp;gt;&amp;gt; bei weniger einen deutlichen Preisvorteil&lt;br /&gt;
* ab 0,85 EUR (Stand 2010)&lt;br /&gt;
&#039;&#039;&#039;Nachteil gegenüber LPC1700:&#039;&#039;&#039;&lt;br /&gt;
* Nur 72 MHz statt 100 MHz Taktfrequenz&lt;br /&gt;
&#039;&#039;&#039;Vorteile gegenüber anderen &amp;quot;Kleinen&amp;quot; wie z.B. PIC, Atmel usw.&#039;&#039;&#039;&lt;br /&gt;
* nahezu gleicher Preis bei Hobby Anwendungen&lt;br /&gt;
* 32 Bit ohne Umwege in Assembler rechenbar&lt;br /&gt;
* bessere Peripherie&lt;br /&gt;
* ... und weitere 1000 Punkte ...&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Nachteil für Hoppy-Anwender&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Nicht direkt &amp;quot;Steckbrettauglich&amp;quot;, da kein DIL Gehäuse verfügbar. Der ebay-Shop dipmicro führt jedoch sehr günstige Lötadapter für Umsetzung von LQFP48 auf DIP48.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Software/Programmierung: ==&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
Als Programmieroberfläche kann eine kostenlose Struktur verwendet werden (wie meinen?):&lt;br /&gt;
&lt;br /&gt;
* Eclipse&lt;br /&gt;
* Coudesourcery Light&lt;br /&gt;
* OpenOCD&lt;br /&gt;
* Yagarto Tools&lt;br /&gt;
* Eclipse Plugin &amp;quot;GDB Hardware Debugging&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Folgende Umgebungen sind als Demoversion (32k Codesize) verfügbar, idR sind dutzende von Examples dabei:&lt;br /&gt;
&lt;br /&gt;
* Keil µVision (www.keil.com)&lt;br /&gt;
* IAR (www.iar.com)&lt;br /&gt;
&lt;br /&gt;
Programmieradapter&lt;br /&gt;
* J-Link / J-Trace Cortex-M3  (www.segger.com), als NonComercial für ca. 60,- zu haben, läuft in µVision, IAR, gdb&lt;br /&gt;
* z.B. OpenOCD ARM-USB-OCD (nicht kostenlos)&lt;br /&gt;
* Keil ULINK2, ULINK pro&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Installation für STM32&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Eclipse &amp;quot;Galileo&amp;quot; installation:&lt;br /&gt;
    http://www.eclipse.org/ &amp;gt;&amp;gt; Downloads &amp;gt;&amp;gt; &amp;quot;Eclipse IDE for C/C++ Developers (79 MB)&amp;quot;&lt;br /&gt;
    http://www.eclipse.org/downloads/download.php?file=/technology/epp/downloads/release/galileo/SR1/eclipse-cpp-galileo-SR1-win32.zip&lt;br /&gt;
    Entpacken der Datei eclipse-cpp-galileo-SR1-win32.zip nach &amp;quot;C:\WinARM\&amp;quot; (Ordner neu erstellen)&lt;br /&gt;
&lt;br /&gt;
* Yagarto Tools:&lt;br /&gt;
    http://www.yagarto.de/ &amp;gt;&amp;gt; &amp;quot;Download (for Windows)&amp;quot; &amp;gt;&amp;gt; &amp;quot;YAGARTO Tools&amp;quot;&lt;br /&gt;
    http://www.yagarto.de/download/yagarto/yagarto-tools-20091223-setup.exe&lt;br /&gt;
    Installieren, Auswahl Verzeichnis &amp;quot;C:\WinARM\yagarto-tools&amp;quot;&lt;br /&gt;
&lt;br /&gt;
* CodeSourcery:&lt;br /&gt;
    http://www.codesourcery.com/ &amp;gt;&amp;gt; Products&amp;gt;Sourcery G++&amp;gt;Editions&amp;gt;Lite &amp;gt;&amp;gt; Try Now&lt;br /&gt;
    http://www.codesourcery.com/downloads/public/public/gnu_toolchain/arm-none-eabi/arm-2009q3-68-arm-none-eabi.exe&lt;br /&gt;
    Installieren, Auswahl Verzeichnis &amp;quot;C:\WinARM\CodeSourcery&amp;quot;&lt;br /&gt;
&lt;br /&gt;
* OpenOCD, kompilliert von Martin-Thomas:&lt;br /&gt;
    http://www.siwawi.arubi.uni-kl.de/avr_projects/arm_projects/winarmtests/&lt;br /&gt;
    Die letzte Version ist &amp;quot;dont_download_this_OpenOCD_package_V0_3_1_mthomas.zip&amp;quot;&lt;br /&gt;
    Die aktuellste ist im Sourceforge als Quelldateien.&lt;br /&gt;
&lt;br /&gt;
* ST Firmware:&lt;br /&gt;
    http://www.st.com &amp;gt;&amp;gt; Auswahl CPU STM32F103xxx &amp;gt;&amp;gt; &amp;quot;Firmware&amp;quot; &amp;quot;STM32F10x_StdPeriph_Lib&amp;quot;&lt;br /&gt;
    http://www.st.com/mcu/devicedocs-STM32F103RC-110.html&lt;br /&gt;
    In dem ZIP ist ein ZIP mit der Firmware &amp;quot;\Archive\um0427.zip&amp;quot;&lt;br /&gt;
    Das ZIP &amp;quot;stm32f10x_stdperiph_lib.zip&amp;quot; Entpacken nach &amp;quot;C:\WinARM\examples\stm32_FW3.2.0\&lt;br /&gt;
&lt;br /&gt;
Eclipse:&lt;br /&gt;
Help &amp;gt;&amp;gt; Install New Software... &amp;gt;&amp;gt; http://download.eclipse.org/tools/cdt/releases/galileo&lt;br /&gt;
    &amp;quot;Eclipse C/C++ Development Tools&amp;quot; + &amp;quot;Eclipse C/C++ GDB Hardware Debugging&amp;quot; installieren&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Installation für STM32 auf einem zweiten Rechner (Eclipse/GCC Installation):&#039;&#039;&#039;&lt;br /&gt;
* Kopieren des Verzeichnisses C:\WinARM\&lt;br /&gt;
* Die PATH-Variable in der Systemsteuerung mit den C:\WinARM.... Verzeichnissen nachführen&lt;br /&gt;
* Fertig.&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Demo-Projekte: ==&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
Martin Thomas hat ein umfangreiches Projekt erstellt, in der die Eclipse Einstellungen enthalten sind:&lt;br /&gt;
&lt;br /&gt;
&amp;quot;ChaN&#039;s FAT-Module with STM32 SPI&amp;quot;&lt;br /&gt;
http://www.siwawi.arubi.uni-kl.de/avr_projects/arm_projects/arm_memcards/index.html&lt;br /&gt;
&lt;br /&gt;
== Bezugsquellen ==&lt;br /&gt;
Versandhäuser für Privatpersonen:&lt;br /&gt;
* TME.eu: http://www.tme.eu/de/katalog/index.phtml#cleanParameters%3D1%26search%3DSTM32F10%26bf_szukaj%3D+&lt;br /&gt;
* Darisus: http://darisusgmbh.de/shop/index.php?cat=c2692_ARM-Cortex.html&lt;br /&gt;
* Sander: http://www.sander-electronic.de/be00069.html&lt;br /&gt;
&lt;br /&gt;
Gewerblich lieferen natürlich viele wie Farnell, Digikey usw.&lt;/div&gt;</summary>
		<author><name>80.72.130.218</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=STM32&amp;diff=45890</id>
		<title>STM32</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=STM32&amp;diff=45890"/>
		<updated>2010-04-08T08:45:49Z</updated>

		<summary type="html">&lt;p&gt;80.72.130.218: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;&lt;br /&gt;
== STM32 ==&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Der STM32 ist ein Mikrocontroller von ST ([www.st.com]http://www.st.com/mcu/inchtml-pages-stm32.html) mit einer 32-Bit ARM Cortex-M3 CPU. (http://www.arm.com/products/processors/cortex-m/index.php). Diese Architektur ist speziell für den Einsatz in Microcontrollern neu entwickelt, und löst damit die bisherigen ARM7 basierten Controller weitestgehend ab.&lt;br /&gt;
Den STM32 gibt es von ST in unzähligen Varianten mit variabler Peripherie und verschiedenen Gehäusegrössen und -formen. &lt;br /&gt;
Durch u.a. die geringe benötigte Chipfläche des Core ist es ST möglich, eine 32 Bit-CPU für weniger als 1 EUR an zu bieten.&lt;br /&gt;
* Cortex-M3 Kern&lt;br /&gt;
* 16KB ... 1MB Flash-ROM und bis zu 64KB SRAM&lt;br /&gt;
* Gehäuse 36 ... 144 Pins als QFN, LQFP und BGA&lt;br /&gt;
* Derzeit bis 72MHz, Modelle bis 120MHz sind angekündigt&lt;br /&gt;
* Externes Businterface&lt;br /&gt;
* Spannungsbereich 2,0 ... 3,6V&lt;br /&gt;
* Bis zu 112 IOs, viele davon 5V-tolerant&lt;br /&gt;
* Interner kalibrierter RC-Oszillator mit 8MHz&lt;br /&gt;
* Externer Quarz&lt;br /&gt;
* Real-Time-Clock mit eigenem Quarz und separater Stromversorgung&lt;br /&gt;
* Bis zu 11 Timer, je Timer bis zu 4 IC/OC/PWM Ausgänge. Davon 2x Motion Control Timer&lt;br /&gt;
* Systick Counter&lt;br /&gt;
* Bis zu 3 12-Bit AD-Wandler mit insgesamt 16 AD-Eingängen&lt;br /&gt;
* Bis zu 2 DMA Controller mit jeweils bis zu 12 Kanälen&lt;br /&gt;
* JTAG und SWD (Single Wire Debug) Interface&lt;br /&gt;
* Bis zu 2x I²C&lt;br /&gt;
* Bis zu 5x USART mit LIN, IrDA und Modem Control&lt;br /&gt;
* Bis zu 2x CAN&lt;br /&gt;
* USB 2.0 Full Speed&lt;br /&gt;
* SDIO Interface (z.B. SD-Card Reader)&lt;br /&gt;
* Ethernet&lt;br /&gt;
* ... (Siehe Datenblätter)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Struktur der Dokumentation: ==&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Als Beispiel der Dokumentation zeige ich mal stellvertretend den STM32F103RC. Die Seite von ST: http://www.st.com/mcu/devicedocs-STM32F103RC-110.html&lt;br /&gt;
Beinhaltet alle nötigen Informationen/Dateien/Dokumente passend zu diesem Prozessor.&lt;br /&gt;
&lt;br /&gt;
Diese Dokumente von ST beschreiben den Controller:&lt;br /&gt;
&lt;br /&gt;
* Datasheet &amp;quot;STM32F103xC/D/E&amp;quot; oder einer anderen Modellreihe&lt;br /&gt;
* Reference Manual &amp;quot;RM0008&amp;quot;&lt;br /&gt;
* Cortex-M3 Programming Manual &amp;quot;PM0056&amp;quot;&lt;br /&gt;
* Flash Programming Reference &amp;quot;PM0042&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Im Datasheet sind die speziellen Eigenschaften eines bestimmten Modells bzw. einer Modellreihe beschrieben und die exakten Daten und Pinouts aufgeführt. Die Peripheriemodule werden nur aufgeführt, nicht detailliert beschrieben. In der Referenz ist der gesamte Controller mit Peripheriemodulen im Detail beschrieben, gültig für alle STM32 Prozessoren. Details zum Prozessor selbst und den nicht STM32-spezifischen mit dem Cortex-M3 Core assoziierten Modulen wie dem Interrupt-Controller und dem Systick-Timer findet man jedoch nicht dort, sondern im Cortex-M3 Manual. Wer nicht die ST Firmware-Library verwendet, der benötigt zusätzlich das Flash Programming Manual für die Betriebsart des Flash-ROMs, d.h. die frequenzabhängige Konfiguration der Waitstates.&lt;br /&gt;
&lt;br /&gt;
Hinzu kommen optionale Dokumente von ARM, die den Cortex-M3 Kern beschreiben.&lt;br /&gt;
Siehe z.B. hier: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.set.cortexm/index.html. Hier gibt es den Opcode wenn man ihn in Assembler programmieren möchte: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0406b/index.html&lt;br /&gt;
&lt;br /&gt;
Zusätzlich sollten auch die Errata Sheets beachtet werden.&lt;br /&gt;
&lt;br /&gt;
Empfohlen sei auch die Appnote: &amp;quot;STM32F10xxx hardware development: getting started&amp;quot; http://www.st.com/stonline/products/literature/an/13675.pdf&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== FW-Lib: ==&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
ST bietet eine umfangreiche FW-LIB Bibliothek. Es ist eine einzige Bibliothek für alle STM32 Derivate. Das ist der große Vorteil von ST. Einmal programmieren und in allen STM32 verwendbar. Alle Funktionen sind gekapselt in einfache Strukturen und Funktionsaufrufe. Somit muss man sich nicht selbst um die Peripherieregister kümmern.&lt;br /&gt;
Die FW-Lib kann ebenfalls von der STM32 Seite kostenlos geladen werden:&lt;br /&gt;
&lt;br /&gt;
* Firmware &amp;quot;STM32F10x_StdPeriph_Lib&amp;quot;&lt;br /&gt;
&lt;br /&gt;
In dem Archiv ist die FW-LIB, zu jeder Peripherie gibt es bis zu 12 Demos und eine Beschreibung als CHM Datei &amp;quot;stm32f10x_stdperiph_lib_um.chm&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== CMSIS: ==&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Parallel zur Firmware-Library gibt es für die &amp;quot;Selbermacher&amp;quot; die CMSIS, die einen Teil der HW und den Core Support abdeckt.&lt;br /&gt;
Im Rahmen des CMSIS Standard (www.onARM.com) wurden die Headerfiles standardisiert, der Zugriff auf die Register erfolgt per &#039;&#039;&#039;Peripheral-&amp;gt;Register&#039;&#039;&#039;. Weiterhin existieren eine Zahl von Helferfunktionen für den NVIC, als auch eine SystemInit - Funktion, welche sich um die PLL kümmert.&lt;br /&gt;
&lt;br /&gt;
== Debug-Interface: ==&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
Als Debug Interface stehen zwei Varianten zur Auswahl:&lt;br /&gt;
* JTAG&lt;br /&gt;
* SWD (Single Wire Debug)&lt;br /&gt;
&lt;br /&gt;
Für JTAG sind 6 Steuerleitungen nötig, für SWD 2 (zzgl GND/3,3V).&lt;br /&gt;
Das SWD Interface verfügt ausserdem über eine weitere Leitung, SWO. Über diesen Kanal kann ein vereinfachtes Trace des Core ermöglicht, sowie printf-like Daten über den ITM Channel 0 geschickt und im Debugger ausgegeben werden.&lt;br /&gt;
&lt;br /&gt;
Die Coresight-Debug-Architektur ermöglicht ein non-invasive debugging, d.h. es können während des Betriebes ohne Beeinflussung des Prozessors Daten vom Speicher gelesen und in selbigen geschrieben werden.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Der 10-Polige JTAG-Stecker:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Ich habe einen 10 Poligen Debug-Stecker entworfen, der alle Varianten sowie einen UART Anschluss enthält:&lt;br /&gt;
&lt;br /&gt;
[[bild:jtag-debug-port10.png]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Die Funktionen:&#039;&#039;&#039;&lt;br /&gt;
* JTAG&lt;br /&gt;
* SWD&lt;br /&gt;
* Debug-UART-Anschluss (verbunden mit einem freien UART vom STM32) (alternativ ein MAX232 Chip dazwischen schalten)&lt;br /&gt;
* Weniger Platzbedarf auf der Platine (Standard-JTAG 20 Polig)&lt;br /&gt;
* Über 4-Poligen Würfel kann der UART benutzt werden (Pin 7/8/9/10)&lt;br /&gt;
* Es kann ein Jumper gesteckt werden für eine Option (Pin 7/8) ohne dass es sich mit dem RS232 Chip beißt (sofern er eingebaut wurde)&lt;br /&gt;
* Über einen 5-Poligen einreihigen Stecker kann SWD (SingleWireDebug) verwendet werden (Pin 1/3/5/7/9)&lt;br /&gt;
* den ganzen Stecker braucht es nur, wenn man den herkömlichen JTAG nutzen möchte.&lt;br /&gt;
* Kurzschlussschutz, da GND und +3V3 nicht gegenüber liegen&lt;br /&gt;
&lt;br /&gt;
In all meinen Projekten verwende ich nur noch diese Anordnung, denn sie ist einfach praktisch. Alles drauf und die Pins sind perfekt angeordnet für jede Art der Anwendung.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Vorteile: ==&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&#039;&#039;&#039;Vorteile gegenüber ARM7:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Interrupt-Controller jetzt Teil des Prozessors (als Core Peripheral), die Vector Table ist jetzt eine echte Vector Tabelle (keine jmps o.ä. wie bei ARM7). Durch automatismen zwischen Core und NVIC (auto register save r0..r3, lr, sp, pc) bei Interrupt Entry wird eine deutlich schnellere Ausführungszeit bei Interrupts erreicht. Der Interrupt Code muss sich nicht mehr selbst um die Sicherung der o.g. Register kümmern. Sind vor Beendigung einer ISR (d.h. Rücksprung zum User Code) weitere Interrupts pending, so werden diese ausgeführt, ohne dass eine komplette pop-push-sequenz der Register notwendig ist.&lt;br /&gt;
* Thumb-2 Befehlssatz wird schneller ausgeführt&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Vorteile gegenüber LPC1700 und LPC1300:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Flexiblere Gehäuseformen mit mehr Peripherie bei kleinen Gehäusen&lt;br /&gt;
* Genauerer ADC, insbesondere gegenüber LPC1300&lt;br /&gt;
* Flexiblere Varianten der Peripherie &amp;gt;&amp;gt; bei weniger einen deutlichen Preisvorteil&lt;br /&gt;
* ab 0,85 EUR (Stand 2010)&lt;br /&gt;
&#039;&#039;&#039;Nachteil gegenüber LPC1700:&#039;&#039;&#039;&lt;br /&gt;
* Nur 72 MHz statt 100 MHz Taktfrequenz&lt;br /&gt;
&#039;&#039;&#039;Vorteile gegenüber anderen &amp;quot;Kleinen&amp;quot; wie z.B. PIC, Atmel usw.&#039;&#039;&#039;&lt;br /&gt;
* nahezu gleicher Preis bei Hobby Anwendungen&lt;br /&gt;
* 32 Bit ohne Umwege in Assembler rechenbar&lt;br /&gt;
* bessere Peripherie&lt;br /&gt;
* ... und weitere 1000 Punkte ...&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Nachteil für Hoppy-Anwender&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Nicht direkt &amp;quot;Steckbrettauglich&amp;quot;, da kein DIL Gehäuse verfügbar. Der ebay-Shop dipmicro führt jedoch sehr günstige Lötadapter für Umsetzung von LQFP48 auf DIP48.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Software/Programmierung: ==&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
Als Programmieroberfläche kann eine kostenlose Struktur verwendet werden (wie meinen?):&lt;br /&gt;
&lt;br /&gt;
* Eclipse&lt;br /&gt;
* Coudesourcery Light&lt;br /&gt;
* OpenOCD&lt;br /&gt;
* Yagarto Tools&lt;br /&gt;
* Eclipse Plugin &amp;quot;GDB Hardware Debugging&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Folgende Umgebungen sind als Demoversion (32k Codesize) verfügbar, idR sind dutzende von Examples dabei:&lt;br /&gt;
&lt;br /&gt;
* Keil µVision (www.keil.com)&lt;br /&gt;
* IAR (www.iar.com)&lt;br /&gt;
&lt;br /&gt;
Programmieradapter&lt;br /&gt;
* J-Link / J-Trace Cortex-M3  (www.segger.com), als NonComercial für ca. 60,- zu haben, läuft in µVision, IAR, gdb&lt;br /&gt;
* z.B. OpenOCD ARM-USB-OCD (nicht kostenlos)&lt;br /&gt;
* Keil ULINK2, ULINK pro&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Installation für STM32&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Eclipse &amp;quot;Galileo&amp;quot; installation:&lt;br /&gt;
    http://www.eclipse.org/ &amp;gt;&amp;gt; Downloads &amp;gt;&amp;gt; &amp;quot;Eclipse IDE for C/C++ Developers (79 MB)&amp;quot;&lt;br /&gt;
    http://www.eclipse.org/downloads/download.php?file=/technology/epp/downloads/release/galileo/SR1/eclipse-cpp-galileo-SR1-win32.zip&lt;br /&gt;
    Entpacken der Datei eclipse-cpp-galileo-SR1-win32.zip nach &amp;quot;C:\WinARM\&amp;quot; (Ordner neu erstellen)&lt;br /&gt;
&lt;br /&gt;
* Yagarto Tools:&lt;br /&gt;
    http://www.yagarto.de/ &amp;gt;&amp;gt; &amp;quot;Download (for Windows)&amp;quot; &amp;gt;&amp;gt; &amp;quot;YAGARTO Tools&amp;quot;&lt;br /&gt;
    http://www.yagarto.de/download/yagarto/yagarto-tools-20091223-setup.exe&lt;br /&gt;
    Installieren, Auswahl Verzeichnis &amp;quot;C:\WinARM\yagarto-tools&amp;quot;&lt;br /&gt;
&lt;br /&gt;
* CodeSourcery:&lt;br /&gt;
    http://www.codesourcery.com/ &amp;gt;&amp;gt; Products&amp;gt;Sourcery G++&amp;gt;Editions&amp;gt;Lite &amp;gt;&amp;gt; Try Now&lt;br /&gt;
    http://www.codesourcery.com/downloads/public/public/gnu_toolchain/arm-none-eabi/arm-2009q3-68-arm-none-eabi.exe&lt;br /&gt;
    Installieren, Auswahl Verzeichnis &amp;quot;C:\WinARM\CodeSourcery&amp;quot;&lt;br /&gt;
&lt;br /&gt;
* OpenOCD, kompilliert von Martin-Thomas:&lt;br /&gt;
    http://www.siwawi.arubi.uni-kl.de/avr_projects/arm_projects/winarmtests/&lt;br /&gt;
    Die letzte Version ist &amp;quot;dont_download_this_OpenOCD_package_V0_3_1_mthomas.zip&amp;quot;&lt;br /&gt;
    Die aktuellste ist im Sourceforge als Quelldateien.&lt;br /&gt;
&lt;br /&gt;
* ST Firmware:&lt;br /&gt;
    http://www.st.com &amp;gt;&amp;gt; Auswahl CPU STM32F103xxx &amp;gt;&amp;gt; &amp;quot;Firmware&amp;quot; &amp;quot;STM32F10x_StdPeriph_Lib&amp;quot;&lt;br /&gt;
    http://www.st.com/mcu/devicedocs-STM32F103RC-110.html&lt;br /&gt;
    In dem ZIP ist ein ZIP mit der Firmware &amp;quot;\Archive\um0427.zip&amp;quot;&lt;br /&gt;
    Das ZIP &amp;quot;stm32f10x_stdperiph_lib.zip&amp;quot; Entpacken nach &amp;quot;C:\WinARM\examples\stm32_FW3.2.0\&lt;br /&gt;
&lt;br /&gt;
Eclipse:&lt;br /&gt;
Help &amp;gt;&amp;gt; Install New Software... &amp;gt;&amp;gt; http://download.eclipse.org/tools/cdt/releases/galileo&lt;br /&gt;
    &amp;quot;Eclipse C/C++ Development Tools&amp;quot; + &amp;quot;Eclipse C/C++ GDB Hardware Debugging&amp;quot; installieren&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Installation für STM32 auf einem zweiten Rechner (Eclipse/GCC Installation):&#039;&#039;&#039;&lt;br /&gt;
* Kopieren des Verzeichnisses C:\WinARM\&lt;br /&gt;
* Die PATH-Variable in der Systemsteuerung mit den C:\WinARM.... Verzeichnissen nachführen&lt;br /&gt;
* Fertig.&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Evaluation-Boards: ==&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
* http://shop.embedded-projects.net/index.php?module=artikel&amp;amp;action=gruppe&amp;amp;id=14&lt;br /&gt;
* http://www.watterott.com/de/Boards-Kits/ARM/ARM-Cortex-M3&lt;br /&gt;
* http://www.sander-electronic.de/es0028.html&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Demo-Projekte: ==&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
Martin Thomas hat ein umfangreiches Projekt erstellt, in der die Eclipse Einstellungen enthalten sind:&lt;br /&gt;
&lt;br /&gt;
&amp;quot;ChaN&#039;s FAT-Module with STM32 SPI&amp;quot;&lt;br /&gt;
http://www.siwawi.arubi.uni-kl.de/avr_projects/arm_projects/arm_memcards/index.html&lt;br /&gt;
&lt;br /&gt;
== Bezugsquellen ==&lt;br /&gt;
Versandhäuser für Privatpersonen:&lt;br /&gt;
* TME.eu: http://www.tme.eu/de/katalog/index.phtml#cleanParameters%3D1%26search%3DSTM32F10%26bf_szukaj%3D+&lt;br /&gt;
* Darisus: http://darisusgmbh.de/shop/index.php?cat=c2692_ARM-Cortex.html&lt;br /&gt;
* Sander: http://www.sander-electronic.de/be00069.html&lt;br /&gt;
&lt;br /&gt;
Gewerblich lieferen natürlich viele wie Farnell, Digikey usw.&lt;/div&gt;</summary>
		<author><name>80.72.130.218</name></author>
	</entry>
</feed>