<?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=Avrprogger</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=Avrprogger"/>
	<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/articles/Spezial:Beitr%C3%A4ge/Avrprogger"/>
	<updated>2026-04-05T22:34:11Z</updated>
	<subtitle>Benutzerbeiträge</subtitle>
	<generator>MediaWiki 1.39.7</generator>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=STM32_-_Einstieg_mit_Em::Blocks&amp;diff=82100</id>
		<title>STM32 - Einstieg mit Em::Blocks</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=STM32_-_Einstieg_mit_Em::Blocks&amp;diff=82100"/>
		<updated>2014-03-18T20:32:21Z</updated>

		<summary type="html">&lt;p&gt;Avrprogger: lö&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In diesem Tutorial werde ich versuchen, möglichst einfach, die ersten Schritte zur Entwicklung von STM32 Anwenungen mit der Em::Blocks IDE zu erklären. Hier soll nicht so stark auf die einzelnen Peripherie-Module der Controller eingegangen werden, sondern mehr auf die IDE und die verschieden Libraries, wie die CMSIS Library, die DSP-Library, die Standard-Peripheral-Library, die USB-Library und vllt. über Ethernet. Ich denke ein Kapitel zu FreeRTOS wird es auch geben. Auserdem steht im Vordergrund Sachen wie z.B. booten aus dem SRAM, In-Application-Programming, FPU, Core-Coupled-RAM usw. Mal sehn wie weit ich komme ;)&lt;br /&gt;
&lt;br /&gt;
==Die Entwicklungsumgebung==&lt;br /&gt;
===Hardware===&lt;br /&gt;
Zum testen der Anwendungen, benutze ich das STM32F4-Discovery Board, welches einen Debugger, Peripherie und natürlich einen STM32 Controller (STM32F407VGT6) enthält. Deshalb sind alle Beispiele hier für den STM32F407VG Controller ausgelegt, können aber meisten 1:1 auf andere Controller portiert werden. Ich werde auch möglichsts keine STM32F4-Discovery Board spezifischen Libraries verwenden, damit der Portierungs-Vorgang möglichsts einfach bleibt.&lt;br /&gt;
&lt;br /&gt;
===Software===&lt;br /&gt;
In diesem Tutorial verwende ich [http://www.emblocks.org/ Em::Blocks] als IDE. Em::Blocks ist eine kostenlose, uneingeschränkte IDE, die alle STM32 Mikrcontroller unterstützt und sehr einfach zu bedienen ist.&lt;br /&gt;
nach dem Download kann die IDE per Dialog, sehr einfach, installiert werden. Als Compiler beinhaltet Em::Blocks den &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
Die IDE unterstützt zurzeit den ST-Link, den J-Link und es gibt eine Generic-Vorlage, durch welche andere Debugger konfiguriert werden können.&lt;br /&gt;
&lt;br /&gt;
Außerdem muss noch der passende Treiber für den Debugger installiert werden. Verwendet man ein Discovery-Board muss der [http://www.st.com/web/catalog/tools/FM146/CL1984/SC724/SS1677/PF251168 ST-Link/V2]-Treiber heruntergeladen und installiert werden. (Die Installation muss evtl. als Administrator ausgeführt werden, da sonst die Installation unvollständig wird.) Nach der Installation des Treibers kann man den Debugger über die entsprechende USB Schnittstelle an den PC anschließen und es sollte die Meldung von Windows kommen, dass der richtige Treiber gefunden wurde.&lt;br /&gt;
&lt;br /&gt;
===Libraries===&lt;br /&gt;
Zum programmieren benötigt man noch die [http://www.arm.com/products/processors/cortex-m/cortex-microcontroller-software-interface-standard.php CMSIS] und die Standard-Peripheral-Library (z.B. für die F4 Controller [http://www.st.com/stonline/stappl/productcatalog/app?page=partNumberSearchPage&amp;amp;levelid=SS1577&amp;amp;parentid=1743&amp;amp;resourcetype=SW Standard-Peripheral-Library-F4]), die man am besten in einen Ordner (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\STM32&#039;&#039;&#039;&#039;&#039;) entpackt&lt;br /&gt;
&lt;br /&gt;
==Basis-Wissen zur IDE==&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von Dateien zum Projekt===&lt;br /&gt;
Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf &amp;lt;ProjektName&amp;gt; -&amp;gt; Add files...&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Enfernen von Dateien aus dem Projekt===&lt;br /&gt;
Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf die Datei / mehrere Dateien auswählen -&amp;gt; Remove file from project&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
Die Dateien werden lediglich aus dem Projekt entfernt und nicht von der Festplatte gelöscht.&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von Include-Pfaden===&lt;br /&gt;
Sofern die Include-Datei(en) nicht im standard Include-Ordner &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; des Projektes liegen, muss man den Pfad zum Projekt hinzufügen, damit der Compiler die Include-Dateien später auch finden kann. Man geht wie folgt vor: Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; Search Directories -&amp;gt; Add&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von globalen Defines zum Build===&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; #defines&#039;&#039;&#039;&#039;&#039; können globale Defines hinzugefügt werden.&lt;br /&gt;
&lt;br /&gt;
===Compilieren===&lt;br /&gt;
Entweder über das &#039;&#039;&#039;&#039;&#039;Build&#039;&#039;&#039;&#039;&#039; Menü oder über &#039;&#039;&#039;&#039;&#039;F7&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Um eine genau Ausgabe des Compiler-Aufrufes mit allen Argumenten zu bekommen, geht man im &#039;&#039;&#039;&#039;&#039;Settings&#039;&#039;&#039;&#039;&#039; Menü auf &#039;&#039;&#039;&#039;&#039;Tools...&#039;&#039;&#039;&#039;&#039; und dann auf &#039;&#039;&#039;&#039;&#039;Toolchain executables&#039;&#039;&#039;&#039;&#039;. Ganz unten, unter &#039;&#039;&#039;&#039;&#039;Logging&#039;&#039;&#039;&#039;&#039; kann man dann &#039;&#039;&#039;&#039;&#039;Full command line&#039;&#039;&#039;&#039;&#039; auswählen.&lt;br /&gt;
&lt;br /&gt;
====Compiler Optionen====&lt;br /&gt;
=====Optimierung=====&lt;br /&gt;
Standardmäßig verwendet Em::Blocks keine Optimierung. Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; Categories: Optimization&#039;&#039;&#039;&#039;&#039; kann zwischen verschieden Optimierungen ausgewählt werden.&lt;br /&gt;
&lt;br /&gt;
=====Verschiedene C-Standards=====&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; Categories: Language standard&#039;&#039;&#039;&#039;&#039; kann man zwischen verschieden C-Standard auswählen, wie z.B, C99.&lt;br /&gt;
(Mit C99 können auch die Lauf-Variable in der for-Schleife deklariert werden: for(int i;..))&lt;br /&gt;
&lt;br /&gt;
===Debuggen===&lt;br /&gt;
*Als erstes den Debugger starten über das &#039;&#039;&#039;&#039;&#039;Debug&#039;&#039;&#039;&#039;&#039; Menü und &#039;&#039;&#039;&#039;&#039;Start/stop Debug Session&#039;&#039;&#039;&#039;&#039; oder über &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
*Danach läuft die Anwendung auf dem Controller und warten im &#039;&#039;&#039;&#039;&#039;Reset_Handler&#039;&#039;&#039;&#039;&#039; auf Einzelschritt- bzw. Run- Befehle (&#039;&#039;&#039;&#039;&#039;F5, F10, F11&#039;&#039;&#039;&#039;&#039; usw..(siehe &#039;&#039;&#039;&#039;&#039;Debug-Menü&#039;&#039;&#039;&#039;&#039; für alle Möglichkeiten))&lt;br /&gt;
&lt;br /&gt;
*Mit &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039; wird die Debug-Session auch wieder beendet&lt;br /&gt;
&lt;br /&gt;
*Unter &#039;&#039;&#039;&#039;&#039;Debug -&amp;gt; Interfaces -&amp;gt; Target settings&#039;&#039;&#039;&#039;&#039; können Eigenschaften, wie z.B &#039;&#039;&#039;&#039;&#039;Run to main()&#039;&#039;&#039;&#039;&#039; aktiviert werden.&lt;br /&gt;
&lt;br /&gt;
====Register View====&lt;br /&gt;
Damit man beim Debuggen sich bequem die Werte der Register (der Peripherie-Register) ansehen kann, bracht man eine, zum Controller passende &#039;&#039;&#039;&#039;&#039;System View Description&#039;&#039;&#039;&#039;&#039;-Datei (*.svd), die die verschiedenen Register beschreibt (Name, Adresse, usw..). In Em::Blocks gibt es dazu ein Tool, womit man solche Dateien herunterladen und verwenden kann.&lt;br /&gt;
&lt;br /&gt;
Um sich die nur die Core-Register anzusehen / zu bearbeiten braucht man keine SVD-Datei.&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;&#039;&#039;&#039;Debug&#039;&#039;&#039;&#039;&#039; -&amp;gt; &#039;&#039;&#039;&#039;&#039;Plugins&#039;&#039;&#039;&#039;&#039; -&amp;gt; &#039;&#039;&#039;&#039;&#039;SVD repository&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Controller-Hersteller und Cntroller-Reihe auswählen&lt;br /&gt;
*Speicherort auswählen (Standard ist das aktuelle Projekt-Verzeichniss)&lt;br /&gt;
*Wenn das Häkchen bei &#039;&#039;&#039;&#039;&#039;Set and launch target debug configuration&#039;&#039;&#039;&#039;&#039; gesetzt ist, öffnen sich die Debug-Einstellungen automatisch, und das neue SVD-File wird verwenden.&lt;br /&gt;
*Debug-Einstellungen mit &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; schließen&lt;br /&gt;
&lt;br /&gt;
===Projekt als Template abspeichern===&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;File -&amp;gt; Save project as template...&#039;&#039;&#039;&#039;&#039;. Das Template erscheint dann im Projekt-Dialog unter &#039;&#039;&#039;&#039;&#039;User templates&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Das erste Projekt erstellen==&lt;br /&gt;
Hier erkläre ich, wie man am Besten (aus meiner Sicht), ein neues Projekt von Grund auf erstellt, sodass man hinterher, den Controller-Kern über die CMSIS-Library und die Peripherie über die Register steuern kann.&lt;br /&gt;
&lt;br /&gt;
===1. Projekt mit der IDE erstellen===&lt;br /&gt;
Nach der Installation der oben beschriebenen Komponenten erstellt man am besten ein Verzeichnis (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\EmBlocks&#039;&#039;&#039;&#039;&#039;), indem später alle Projekte gespeichert werden. Für Libraries kann man auch noch ein Verzeichnis (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\STM32&#039;&#039;&#039;&#039;&#039;) erstellen, wo alle Libraries gespeichert werden, die man für die Projekt brauchen.&lt;br /&gt;
&lt;br /&gt;
Als nächstes starten man EmBlocks. Bei dem ersten Start öffnet sich ein Fenster, wo verschiedene Compiler angezeigt werden, die Em::Blocks findet. Dort wählt man den &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039; aus und klickt &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039;. Nun sollte sich das Hauptfenster von Em::Blocks öffnen. Über &#039;&#039;&#039;&#039;&#039;Create a new Project&#039;&#039;&#039;&#039;&#039; oder &#039;&#039;&#039;&#039;&#039;File -&amp;gt; New -&amp;gt; Project&#039;&#039;&#039;&#039;&#039; ruft man den Projekt-Dialog auf und kann ein neues Projekt erzeugen.&lt;br /&gt;
&lt;br /&gt;
Auf der Ersten Seite wählen man den &#039;&#039;&#039;&#039;&#039;STmicro-ARM&#039;&#039;&#039;&#039;&#039; Projekt-Typ aus.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_1.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auf der nächsten Seite wird man darauf hingewiesen, dass das der entsprechende Projekt-Typ-Dialog ausgeführt wird. Hier kann man ein Häkchen bei &#039;&#039;&#039;&#039;&#039;Skip this page next time&#039;&#039;&#039;&#039;&#039; setzen und auf &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; klicken.&lt;br /&gt;
&lt;br /&gt;
Im nächsten Schritt wählen man das zuvor erstellt Verzeichnis unter &#039;&#039;&#039;&#039;&#039;Folder to create Project in&#039;&#039;&#039;&#039;&#039; aus, indem später alle Projekt gespeichert werden. Außerdem geben wir dem Projekt einen Namen (z.B. &#039;&#039;&#039;&#039;&#039;FirstProject&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_2.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danach muss man einen Compiler auswählen und bestimmen, welche Projekt-Konfigurationen erszeugt werden sollen. Unter &#039;&#039;&#039;&#039;&#039;Compiler&#039;&#039;&#039;&#039;&#039; wählt man &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039; und man kann das Häkchen bei &#039;&#039;&#039;&#039;&#039;Create &amp;quot;Release&amp;quot; configuration&#039;&#039;&#039;&#039;&#039; entfernen, da diese unnötig ist, die Debug-Konfiguration sollte eig. immer ausreichen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_3.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auf den folgenden Seite wird der Controller ausgewählt. Verwendet man ein STM32F4-Discovery Board müssen folgende Dinge gewählt werden: &#039;&#039;&#039;&#039;&#039;Cortex_M4 (F3xx - F4xx) -&amp;gt; STM32F4xx (Cortex M4 with FPU) -&amp;gt; STM32F407VG&#039;&#039;&#039;&#039;&#039;. Leider sind die Auswahl Möglichkeiten nicht ganz richtig, da auch die F3 Controller einen Cortex M4 Kern und eine FPU haben (Ist aber nicht so wichtig, ist nur eine formale Sache). Außerdem entfernt man das Häkchen bei &#039;&#039;&#039;&#039;&#039;Standard Peripherals Library&#039;&#039;&#039;&#039;&#039; (Wie man die Standard-Peripheral-Library einbindet und verwendet erkläre ich später). Man kann auch das Häkchen bei &#039;&#039;&#039;&#039;&#039;Create hex file for Realease target&#039;&#039;&#039;&#039;&#039; entfernen.&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;Stack Size&#039;&#039;&#039;&#039;&#039; und &#039;&#039;&#039;&#039;&#039;Heap Size&#039;&#039;&#039;&#039;&#039; wird die Größe von Stack und Heap festgelegt. Für eine erste Anwendung kann man die Einstellungen so lassen (Stack-Size: 0x0100 =&amp;gt; 256 Byte Stack und Heap-Size: 0x0000 =&amp;gt; kein Heap). Mit &#039;&#039;&#039;&#039;&#039;Finish&#039;&#039;&#039;&#039;&#039; ist der Projekt Dialog abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_4.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danach sollten sich zwei neue Fenster öffnen, um die Debug-Eigenschaften fest zu legen.&lt;br /&gt;
Verwendet man ein Discovery Board/ST-Link müssen die Einstellungen wie auf dem Bild gewählt werden. Über den Button &#039;&#039;&#039;&#039;&#039;Settings&#039;&#039;&#039;&#039;&#039; öffnet sich das zweite Fenster, falls sich dieses nicht schon von alleine öffnen sollte. Nach den Schließen der Fenster über &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; ist der Projekt Dialog beendet und ein neues Projekt steht zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_5_1.png|Debug Eigenschaften 1. Fenster]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_5_2.png|Debug Eigenschaften 2. Fenster]]&lt;br /&gt;
&lt;br /&gt;
===2. CMSIS-Library und Startup-Code hinzufügen===&lt;br /&gt;
Wenn man sich, nachdem man ein neues Projekt in der IDE erstellt hat, die bereits vorhandenen Dateien im Projekt ansieht, stellt man fest, das bereits ein Ordner &#039;&#039;&#039;&#039;&#039;cmsis&#039;&#039;&#039;&#039;&#039; existiert, der einige wichtige Include-Dateien der CMSIS-Library enthält. Allerdings sind das wirklich nur die wichtigsten Include-Dateien der CMSIS-Library und dazu noch, die aus einer älternen Version. Ich ziehe es deshalb vor die &amp;quot;Mini-CMSIS-Libraray&amp;quot; und die &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c/.h&#039;&#039;&#039;&#039;&#039; Dateien des Projektes durch aktuellere Versionen zu ersetzen. So ist später auch die Integration  von anderen Libraries, wie z.B. der CMSIS-DSP-Libarary einfacher.  &lt;br /&gt;
&lt;br /&gt;
Zunächst gehen man in das Projekt-Verzeichnis und löscht:&lt;br /&gt;
*Den Ordner &#039;&#039;&#039;&#039;&#039;cmsis&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Alle Dateien im Include Verzeichnis &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; im &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner&lt;br /&gt;
&lt;br /&gt;
Außerdem entfernt man auch alle gelöschten Dateien in der IDE aus dem Projekt mit &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Rechts Klick -&amp;gt; Remove file from project&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Es sollte folgende Verzeichnis Struktur überbleiben:&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_6.png|Überbleibende Dateien]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Jetzt müssen die gelöschten Dateien durch die aktuelleren ersetzt werden.&lt;br /&gt;
&lt;br /&gt;
*Dazu kopieren man den gesamten Ordner &#039;&#039;&#039;&#039;&#039;CMSIS&#039;&#039;&#039;&#039;&#039; aus dem CMSIS Download in das Projekt Verzeichnis.&lt;br /&gt;
&lt;br /&gt;
*Aus dem Standard-Peripheral-Library Download kopiert man von &#039;&#039;&#039;&#039;&#039;Libraries\CMSIS\Device\ST\STM32F4xx\Include&#039;&#039;&#039;&#039;&#039; alle Dateien in den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projekt Verzeichnisses&lt;br /&gt;
&lt;br /&gt;
*Aus der Standard-Peripheral-Library kopieren man ebenfalls von &#039;&#039;&#039;&#039;&#039;Libraries\CMSIS\Device\ST\STM32F4xx\Source\Templates&#039;&#039;&#039;&#039;&#039; die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; in den &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner des Projekts&lt;br /&gt;
&lt;br /&gt;
Anschließend müssen die neuen Dateien in der IDE dem Projekt hinzugefügt werden. Dazu benutzt man &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Rechts Klick -&amp;gt; Add files&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
*Aus dem &#039;&#039;&#039;&#039;&#039;CMSIS&#039;&#039;&#039;&#039;&#039; Ordner im Projekt Verzeichnis werden aus den Unterorder &#039;&#039;&#039;&#039;&#039;Include&#039;&#039;&#039;&#039;&#039; folgende Dateien dem Projekt hinzugefügt:&lt;br /&gt;
**arm_common_tables.h&lt;br /&gt;
**arm_const_structs.h&lt;br /&gt;
**arm_math.h&lt;br /&gt;
**core_cm4.h&lt;br /&gt;
**core_cm4_simd.h&lt;br /&gt;
**core_cmFunc.h&lt;br /&gt;
**core_cmInstr.h&lt;br /&gt;
*Alle Dateien aus den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projektes&lt;br /&gt;
*Die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; aus dem &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner&lt;br /&gt;
&lt;br /&gt;
So sollte die Struktur dann aussehen:&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_7.png|Anwenungs-Grundgerüst]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Da einige Dateien der Libraries später bearbeitet werden müssen und Schreibgeschützt sind, weise ich hier schonmal darauf hin, das der Schreibschutz in der IDE über &#039;&#039;&#039;&#039;&#039;Rechts Klick auf die Datei -&amp;gt; Properties -&amp;gt; Häkchen bei &amp;quot;File is read only&amp;quot; entfernen&#039;&#039;&#039;&#039;&#039; entfert werden kann.&lt;br /&gt;
&lt;br /&gt;
Damit die IDE die Header-Dateien der CMSIS Library auch finden kann, weil diese ja nicht im standard Include Ordner &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; liegen, muss unter &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Build Options -&amp;gt; Search Directories&#039;&#039;&#039;&#039;&#039; der Pfad &#039;&#039;&#039;&#039;&#039;CMSIS\Include&#039;&#039;&#039;&#039;&#039; hinzugefügt werden.&lt;br /&gt;
&lt;br /&gt;
Compiliert man jetzt das Projekt mit &#039;&#039;&#039;&#039;&#039;F7&#039;&#039;&#039;&#039;&#039; gibt es ein paar Fehler Meldungen, weil keine Controller-Reihe ausgewählt wurde. Ebenfalls unter &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Build Options -&amp;gt; Compiler Settings -&amp;gt; #defines&#039;&#039;&#039;&#039;&#039; wird der Define &#039;&#039;&#039;&#039;&#039;STM32F40_41xxx&#039;&#039;&#039;&#039;&#039; hinzugefügt.&lt;br /&gt;
&lt;br /&gt;
Beim erneuten Compilieren sollten sich nun keine neuen Fehler ergeben.&lt;br /&gt;
&lt;br /&gt;
===3. Das erste Programm===&lt;br /&gt;
Nachdem ein grundsätzliches &amp;quot;Gerüst&amp;quot; fertig ist, kann man den ersten Code schreiben.&lt;br /&gt;
main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC-&amp;gt;AHB1ENR |= RCC_AHB1ENR_GPIODEN;    //Takt für GPIO aktivieren&lt;br /&gt;
    GPIOD-&amp;gt;MODER |= GPIO_MODER_MODER15_0;   //GPIOD Pin15 als Ausgang&lt;br /&gt;
    GPIOD-&amp;gt;BSRRL |= GPIO_BSRR_BS_15;        //GPIOD Pin15 auf High ziehen&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039; wird dann der Debugger gestartet. Hat der Debugger das Projekt erfolgreich übertragen kann die Ausführung mit &#039;&#039;&#039;&#039;&#039;F5&#039;&#039;&#039;&#039;&#039; begonnen werden.&lt;br /&gt;
&lt;br /&gt;
==Libraries einbinden/verwenden==&lt;br /&gt;
Um Libraries, wie hier im Tutorial, einzubinden, wird ein existierendes Projekt, wie ein im Kapitel [http://www.mikrocontroller.net/articles/STM32_-_Einstieg_mit_Em::Blocks#Das_erste_Projekt_erstellen Das Erste Projekt erstellen] beschrieben wird, vorausgesetzt.&lt;br /&gt;
&lt;br /&gt;
===Einbinden der Standard-Peripheral-Library===&lt;br /&gt;
Um nicht immer die einzelnen Register, wie im ersten &amp;quot;bare-metal&amp;quot; Beispiel, aus dem Reference-Manual zu suchen und zu beschreiben, gibt es von ST die Standard Peripheral Library, die diese Aufgaben übernimmt und mit der sich die &amp;quot;normale/grundlegende&amp;quot; (Alles außer USB und Ethernet) Peripherie recht einfach steuern lässt. Ich kopiere die Standard-Peripheral-Library immer per Hand in das Projekt. Darduch hat man auch gleich die aktuellste Version (in den älteren Version gibt es einige Bugs). &lt;br /&gt;
&lt;br /&gt;
*1. Den Ordner &#039;&#039;&#039;&#039;&#039;Libraries\STM32F4xx_StdPeriph_Driver&#039;&#039;&#039;&#039;&#039; aus dem Standard-Peripheral-Library Download in das Projekt-Verzeichnis kopieren&lt;br /&gt;
*2. Die Datei &#039;&#039;&#039;&#039;&#039;Project\STM32F4xx_StdPeriph_Templates\stm32f4xx_conf.h&#039;&#039;&#039;&#039;&#039; ebenfalls aus dem Standard-Peripheral-Library Download in den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projektes kopieren.&lt;br /&gt;
*3. In der IDE den Include-Path &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\inc&#039;&#039;&#039;&#039;&#039; hinzufügen&lt;br /&gt;
*4. Und das/den Define &#039;&#039;&#039;&#039;&#039;USE_STDPERIPH_DRIVER&#039;&#039;&#039;&#039;&#039; hinzufügen&lt;br /&gt;
*4. Source- und Include-Dateien zum Projekt hinzufügen&lt;br /&gt;
**Achtung: Es dürfen nur die Dateien hinzugefügt werden, für die der Controller auch die entsprechende Peripherie bereit stellt. Diese Dateien dürfen nicht beim STM32F4-Discovery/STM32F407VG hinzugefügt werden.&lt;br /&gt;
***stm32f4xx_dma2d.c/.h&lt;br /&gt;
***stm32f4xx_fmc.c/.h&lt;br /&gt;
***stm32f4xx_ltdc.c/.h&lt;br /&gt;
***stm32f4xx_sai.c/.h&lt;br /&gt;
&lt;br /&gt;
Daraus resultiert folgende Struktur:&lt;br /&gt;
&lt;br /&gt;
[[Datei:stdperiphlib_2.png|Header-Struktur]] [[Datei:stdperiphlib_1.png|Source-Struktur]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Anschließen kann die Standard-Peripheral-Library benutz werden.&lt;br /&gt;
main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);&lt;br /&gt;
&lt;br /&gt;
    GPIO_InitTypeDef GPIOD_InitStructure;&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Mode = GPIO_Mode_OUT;     //Als Ausgang&lt;br /&gt;
    GPIOD_InitStructure.GPIO_OType = GPIO_OType_PP;    //Push-Pull Betrieb&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Pin = GPIO_Pin_15;        //Pin 15 (STM32F4-Discovery: Blaue LED)&lt;br /&gt;
    GPIOD_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;  //Kein Pull-Up oder Pull-Down Widerstand aktiviert&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Speed = GPIO_Speed_25MHz; //25MHz Update-Rate&lt;br /&gt;
    GPIO_Init(GPIOD, &amp;amp;GPIOD_InitStructure);&lt;br /&gt;
&lt;br /&gt;
    GPIO_SetBits(GPIOD, GPIO_Pin_15);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hier ist noch ein &amp;quot;BasicFramework&amp;quot;, dass die komplette CMSIS- und Standard-Peripheral-Library enthält und kann Quasi als Basis für alle Projekte verwendet werden. Allerdings ist das Framework primär auf die STM32F405/7 und STM32F415/7 ausgelegt. Die neueren STM32F401, STM32F42X und STM32F43X  haben noch etwas andere Peripherie, dass Framework müsste dann entsprechend angepasst werden. Download: [[Datei:StdPeriphDriver_BasicFramework.zip]]&lt;br /&gt;
&lt;br /&gt;
===Einbinden der DSP-Library===&lt;br /&gt;
STM32F3 / STM32F4 Microcontroller haben neben der FPU noch einen Digital-Signal-Processor (DSP). Die DSP dient hauptsächlich dazu, viele Daten schnell zu verarbeiten (z.B. Video- oder Audiosignal). Der CMSIS-Download beinhaltet dazu neben der eigentlichen CMSIS-Library auch noch eine DSP-Library. Diese Library stellt sowohl einfache, mathematische Funktionen wie addieren, multiplizieren usw. als auch komplexe Funktionen, wie z.B  einen IIR-Filter, zur Verfügung. Die DSP-Library ist weiter aufgeteilt in kleinere Module, wie z.B. BasicMathFunctions, FilteringFunctions usw. (siehe &#039;&#039;&#039;&#039;&#039;CMSIS\DSP-Library\Source&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
*1. Source-Dateien des benötigten Moduls zum Projekt hinzufügen. (&#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Add files...&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
*2. &#039;&#039;&#039;&#039;&#039;arm_math.h&#039;&#039;&#039;&#039;&#039; in der &#039;&#039;&#039;&#039;&#039;main.c&#039;&#039;&#039;&#039;&#039; einbinden&lt;br /&gt;
*3. Damit die Warnung &amp;quot;Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)&amp;quot; verschwindet, muss der Define &#039;&#039;&#039;&#039;&#039;__FPU_PRESENT&#039;&#039;&#039;&#039;&#039; hinzugefügt werden. (Keine Ahnung, wieso es die Warnung gibt)&lt;br /&gt;
 &lt;br /&gt;
Jetzt kann die DSP-Library verwedet werden. Das Beispiel multipliziert zwei Buffer miteinander. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
#include &amp;quot;arm_math.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    float32_t x[1024];&lt;br /&gt;
    float32_t y[1024];&lt;br /&gt;
    float32_t z[1024];&lt;br /&gt;
&lt;br /&gt;
    for(uint16_t i = 0; i &amp;lt; 1024; i++)&lt;br /&gt;
    {&lt;br /&gt;
        x[i] = i;&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for(uint16_t i = 0; i &amp;lt; 1024; i++)&lt;br /&gt;
    {&lt;br /&gt;
        y[i] = PI;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    arm_mult_f32(x, y, z, 1024);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Startup-Code, Linker-Script, Takt, FPU usw.==&lt;br /&gt;
===Startup-Code===&lt;br /&gt;
Em::Blocks fügt standardmäßig einen Startup-Code mit in das Projekt ein. Die wichtigsten Dinge die darin erledigt werden sind folgende:&lt;br /&gt;
&lt;br /&gt;
*Stack und Heap wird angelgt&lt;br /&gt;
*Die Vector-Table wird angelegt&lt;br /&gt;
*Ein Default Reset-Handler wird implementiert, dieser erledigt folgende aufgaben:&lt;br /&gt;
**Kopieren der definierten Daten aus dem Flash in den SRAM&lt;br /&gt;
**&#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; wird aufgerufen, wenn &#039;&#039;&#039;&#039;&#039;__NO_SYSTEM_INIT&#039;&#039;&#039;&#039;&#039; nicht definiert ist&lt;br /&gt;
**Sprung in die &#039;&#039;&#039;&#039;&#039;main()&#039;&#039;&#039;&#039;&#039; Funktion&lt;br /&gt;
*Allen anderen Interrupt-Handler wird eine Default-Funktion &#039;&#039;&#039;&#039;&#039;def_irq_handler&#039;&#039;&#039;&#039;&#039; mit einer &#039;&#039;&#039;&#039;&#039;while(1)&#039;&#039;&#039;&#039;&#039;-Schleife zugewiesen, falls kein anderer Interrupt-Handler existiert.&lt;br /&gt;
&lt;br /&gt;
Normalerweise muss am Startup-Code nichts verändert werden.&lt;br /&gt;
&lt;br /&gt;
===Linker-Script===&lt;br /&gt;
Em::Blocks stellt zwei fertige Linker-Scripts bereit, eins für die Ausführung des Programmes aus dem Flash (&#039;&#039;&#039;&#039;&#039;*_flash.ld&#039;&#039;&#039;&#039;&#039;), das andere für die Ausführung aus dem SRAM (&#039;&#039;&#039;&#039;&#039;*_sram.ld&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Normalerweise muss auch hier nichts geändert werden, es sei den Daten sollen in bestimmten Adressbereichen abgelegt werden (z.B. im Core-Coupled RAM), was ich später noch zum Tutorial hinzufüge.&lt;br /&gt;
&lt;br /&gt;
===Der Takt===&lt;br /&gt;
Jeder Controller oder Prozessor braucht einen Takt, indem er die einzelnen Maschinen-Befehle abarbeiten kann.&lt;br /&gt;
Bei den STM32 Mikrocontrollern kann dieser Takt aus verschiedenen Quellen kommen:&lt;br /&gt;
&lt;br /&gt;
1. High Speed Internal Oszillator (HSI)&lt;br /&gt;
&lt;br /&gt;
2. High Speed External Oszillator (HSE)&lt;br /&gt;
&lt;br /&gt;
3. Low Speed Internal Oszillator (LSI)&lt;br /&gt;
&lt;br /&gt;
4. Low Speed External Oszillator (LSE)&lt;br /&gt;
&lt;br /&gt;
5. Phase-Locked Loop (PLL) (generiert den Takt aus den ersten vier Taktquellen durch Teiler und Faktoren)&lt;br /&gt;
&lt;br /&gt;
Nach einem Reset wird der Controller aus der HSI Taktquelle versorgt (16MHz beim STM32F407VG). Um die voll Performance des Controllers zu erreichen muss die PLL verwendet werden, welche den Takt durch geschickte Teiler und Faktoren vervielfältigt, sodass am Ende der Controller mit der maximalen Taktfrequenz läuft. Die notwendige Initialisierung der PLL findet in der Funktion &#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; statt. Die PLL erzeugt zunächst einen Basistakt:&lt;br /&gt;
&lt;br /&gt;
PLL_VCO = (F_HSE / PLL_M) * PLL_N&lt;br /&gt;
&lt;br /&gt;
Aus diesem Takt wird dann der Takt für den Controller-Kern abgeleitet:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = PLL_VCO / PLL_P&lt;br /&gt;
&lt;br /&gt;
Und der Takt für SDIO / USB / RNG (48MHz):&lt;br /&gt;
&lt;br /&gt;
48MHz = PLL_VCO / PLL_Q&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Durch weiter Teiler werden, die Takte für die einzelnen Busse erzeugt, da diese nicht alle beliebig schnell betrieben werden dürfen.&lt;br /&gt;
&lt;br /&gt;
Genaue Angaben findet man zu dem jeweiligen Clock-System des Controllers im Reference Manual.&lt;br /&gt;
&lt;br /&gt;
Ein Blick in den &amp;quot;Kommentar-Header&amp;quot; verrät, dass von einem externen (HSE) Oszillator von 25MHz ausgegangen wird, der die PLL versorgen soll.&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((25MHz / PLL_M(25)) * PLL_N(336)) / PLL_P(2) = 168MHz&lt;br /&gt;
&lt;br /&gt;
Allerdings stimmt diese Rechnung natürlich nur, wenn wirklich ein 25MHz Quarz am Controller angeschlossen ist. Auf dem STM32F4-Discovery Board befindet sich aber nur ein 8MHz Quarz. Demnach gilt:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((8MHz / PLL_M(25)) * PLL_N(336)) / PLL_P(2) = 53.76MHz&lt;br /&gt;
&lt;br /&gt;
Der Controller läuft also nur mit 53.76MHz, wenn wie ober beschrieben ein Projekt erstellt wird. Allerdings kann dieses Problem durch ändern von den betroffen Defines behoben werden:&lt;br /&gt;
 &lt;br /&gt;
*Dazu geht man in die &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; Datei und passt zur Vollständigkeit erstmal die zum Controller passende Tabelle im &amp;quot;Kommentar-Header&amp;quot; an (Z.57f):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      HSE Frequency(Hz)                      | 8000000&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      PLL_M                                  | 8&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Danach passt man den PPL_M Define (Z.254) an:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/************************* PLL Parameters *************************************/&lt;br /&gt;
/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */&lt;br /&gt;
#define PLL_M      8&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Außerdem muss man den HSE_VALUE Define in der &#039;&#039;&#039;&#039;&#039;inc/stm32f4xx.h&#039;&#039;&#039;&#039;&#039; angepasst werden (Z.122):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#if !defined  (HSE_VALUE)&lt;br /&gt;
  #define HSE_VALUE    ((uint32_t)8000000) /*!&amp;lt; Value of the External oscillator in Hz */&lt;br /&gt;
&lt;br /&gt;
#endif /* HSE_VALUE */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine neue Berechnung zeigt:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((8MHz / PLL_M(8)) * PLL_N(336)) / PLL_P(2) = 168MHz&lt;br /&gt;
&lt;br /&gt;
Jetzt läuft der Controller mit maximaler Geschwindigkeit.&lt;br /&gt;
&lt;br /&gt;
Die Theorie wird durch folgendes Programm verifiziert. Der geviertelte System-Takt SYSCLK wir am Pin PC9 ausgegeben. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);&lt;br /&gt;
&lt;br /&gt;
    GPIO_InitTypeDef GPIOC_InitStructure;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Mode = GPIO_Mode_AF;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_OType = GPIO_OType_PP;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Pin = GPIO_Pin_9;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;&lt;br /&gt;
    GPIO_Init(GPIOC, &amp;amp;GPIOC_InitStructure);&lt;br /&gt;
&lt;br /&gt;
    RCC_MCO2Config(RCC_MCO2Source_SYSCLK, RCC_MCO2Div_4);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Die FPU===&lt;br /&gt;
====Allgemeines====&lt;br /&gt;
STM32F3 und STM32F4 Controller haben eine FPU.&lt;br /&gt;
Damit die FPU richtig verwendet wird, müssen normalerweise zwei Bedingungen erfüllt sein:&lt;br /&gt;
&lt;br /&gt;
1. Der Controller muss die FPU Hardware-seitig aktivieren&lt;br /&gt;
&lt;br /&gt;
2. Damit die FPU auch was zu tuen bekommt, müssen vom Compiler FPU-Instructions erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
Die Em::Blocks IDE verwendet standardmäßig die FPU, wenn eine Vorhanden ist. Hier wird die FPU Hardware-seitig aktiviert (&#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; Z.341):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* FPU settings ------------------------------------------------------------*/&lt;br /&gt;
  #if (__FPU_PRESENT == 1) &amp;amp;&amp;amp; (__FPU_USED == 1)&lt;br /&gt;
    SCB-&amp;gt;CPACR |= ((3UL &amp;lt;&amp;lt; 10*2)|(3UL &amp;lt;&amp;lt; 11*2));  /* set CP10 and CP11 Full Access */&lt;br /&gt;
  #endif&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
__FPU_PRESENT wird in der &#039;&#039;&#039;&#039;&#039;stm32f4xx.h&#039;&#039;&#039;&#039;&#039; definiert.&lt;br /&gt;
__FPU_USED wird von der IDE übernommen (siehe Build-Log): &#039;&#039;&#039;&#039;&#039;-D__FPU_USED&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Außerdem wird der Compiler von der IDE standardmäßig mit dem Argument &#039;&#039;&#039;&#039;&#039;-mfloat-abi=hard&#039;&#039;&#039;&#039;&#039; aufgerufen, wodurch FPU-Instructions erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
====FPU abschalten====&lt;br /&gt;
Um die FPU ab zu schalten (Mir würde jetzt nur Strom sparen als Grund einfallen) geht man wie folgt vor:&lt;br /&gt;
&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; Device -&amp;gt; Policy&#039;&#039;&#039;&#039;&#039; wählt man &#039;&#039;&#039;&#039;&#039;Use target settings&#039;&#039;&#039;&#039;&#039; und über nimmt die Einstellungen, die vorher dort eingetragen waren, allerdings lässt man das Feld &#039;&#039;&#039;&#039;&#039;FP-hardware&#039;&#039;&#039;&#039;&#039; frei.&lt;br /&gt;
&lt;br /&gt;
[[Datei:fpu_1.png|FPU Abschalten Schritt 1]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;Compiler Settings -&amp;gt; Policy&#039;&#039;&#039;&#039;&#039; wählt man dann &#039;&#039;&#039;&#039;&#039;Use target options only&#039;&#039;&#039;&#039;&#039;. Dann kann man unter &#039;&#039;&#039;&#039;&#039;Categories&#039;&#039;&#039;&#039;&#039; die Option &#039;&#039;&#039;&#039;&#039;ARM FPU architecture&#039;&#039;&#039;&#039;&#039; auswählen. Dort stehen dann drei Möglichkeiten für die FPU zur Verfügung:&lt;br /&gt;
&lt;br /&gt;
1. Software-FPU-Library für Gleitkomma-Berechnung verwenden - Keine FPU-Instructions werden generiert (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=soft&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
2. Eine Mischung aus Software- und Hardware-FPU wird verwendet (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=softfp&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
3. Hardware-FPU wird für Gleitkomma-Berechnungen verwendet (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=hard&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
[[Datei:fpu_2.png|FPU Abschalten Schritt 2]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Um die FPU ab zu schalten wählt man natürlich die erste Möglichkeit.&lt;br /&gt;
Bei der 2. und 3. Möglichkeit fügt die IDE auch den Define &#039;&#039;&#039;&#039;&#039;__FPU_USED&#039;&#039;&#039;&#039;&#039; hinzu. Bei Der ersten Möglichkeit nicht. Der Code muss also nicht verändert / auskommentiert werden.&lt;br /&gt;
&lt;br /&gt;
Um die FPU wieder zu aktivieren müssen alle Schritte wieder rückgängig gemacht werden.&lt;br /&gt;
&lt;br /&gt;
Am besten ist es einfach mal alle Möglichkeiten im Einzelschritt durch zu probieren. Dann stellt man schnell fest, ob die FPU aktiviert wir oder nicht. Ein Blick in den erweiterten &#039;&#039;&#039;&#039;&#039;Build-Log&#039;&#039;&#039;&#039;&#039; gibt auch schnell Aufschluss darüber, wie der Compiler aufgerufen wird (siehe Kapitel [http://www.mikrocontroller.net/articles/STM32_-_Einstieg_mit_Em::Blocks#Compilieren Compilieren]).&lt;br /&gt;
&lt;br /&gt;
====Test Programm für die FPU====&lt;br /&gt;
Hier ein kleines Testprogramm, dass misst wie viele Taktzyklen für eine Gleitkomma-Multiplikation gebraucht werden. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define CORE_SysTickEn()    (*((u32*)0xE0001000)) = 0x40000001&lt;br /&gt;
#define CORE_SysTickDis()   (*((u32*)0xE0001000)) = 0x40000000&lt;br /&gt;
#define CORE_GetSysTick()   (*((u32*)0xE0001004))&lt;br /&gt;
&lt;br /&gt;
uint32_t t1, t2, dt;&lt;br /&gt;
float x, y, z;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    x = 53.64f;&lt;br /&gt;
    y = 0.27f;&lt;br /&gt;
&lt;br /&gt;
    CORE_SysTickEn();&lt;br /&gt;
    t1 = CORE_GetSysTick();&lt;br /&gt;
&lt;br /&gt;
    z = x * y;&lt;br /&gt;
&lt;br /&gt;
    t2 = CORE_GetSysTick();&lt;br /&gt;
    CORE_SysTickDis();&lt;br /&gt;
&lt;br /&gt;
    dt = (t2 - t1) - 9; //9 Takt-Zyklen werden für die Messung gebraucht &lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Core-Coupled-RAM verwenden===&lt;br /&gt;
Auf den normale SRAM kann durch den Core und die verschiedenen DMA-Controller zugegriffen werden. Jedoch können Core und DMA nicht gleichzeitig auf den SRAM zugreifen. Deswegen gibt es einen zweiten kleinen RAM, den Core-Coupled-RAM (CCRAM), auf den nur vom Core zugegriffen werden kann und nicht von einem DMA-Controller. Der CCRAM ist über einen anderen Bus an dem Cortex angeschlossen. Daduch wird ermöglicht, dass der Core sinnvoll weiterarbeiten kann, wenn ein DMA-Controller Daten aus den &amp;quot;Haupt&amp;quot;-RAM ließt/schreibt, indem der Core Daten aus dem CCRAM verarbeitet. Um Daten in den CCRAM zu legen, geht man wie folgt vor:&lt;br /&gt;
&lt;br /&gt;
1. Eine neue Section im Linkerscript anlegen:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
Sections:&lt;br /&gt;
{&lt;br /&gt;
  ...&lt;br /&gt;
&lt;br /&gt;
  .ccram :&lt;br /&gt;
  {&lt;br /&gt;
    *(.ccram)&lt;br /&gt;
  } &amp;gt; CCRAM&lt;br /&gt;
&lt;br /&gt;
  ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Um die neue Section zu verwenden benutzt man diesen Define:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#define CCRAM __attribute__((section(&amp;quot;.ccram&amp;quot;)))&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
int CCRAM dataInCCRAM;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Beim Debuggen stellt man fest das die Variable an der Adresse 0x10000000 liegt, der ersten Adresse das CCRAM&#039;s.&lt;br /&gt;
&lt;br /&gt;
==Booten aus dem SRAM==&lt;br /&gt;
STM32 Controller haben die Möglichkeit Code aus dem Flash als auch aus dem SRAM auszuführen. Um eine Anwenung per Debugger in des SRAM zu laden sind nur wenige Schritte erforderlich:&lt;br /&gt;
&lt;br /&gt;
*Um das Linkerscript für den SRAM zu verwenden geht man zu: &#039;&#039;&#039;&#039;&#039;Build options... -&amp;gt; Device&#039;&#039;&#039;&#039;&#039; dort wählt man unter &#039;&#039;&#039;&#039;&#039;Policy&#039;&#039;&#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;Use target settings&#039;&#039;&#039;&#039;&#039; aus und übernimmt die vorherigen Einstellungen, nur unter &#039;&#039;&#039;&#039;&#039;Linker script*&#039;&#039;&#039;&#039;&#039; gibt man &#039;&#039;&#039;&#039;&#039;.\stm32f407vg_sram.ld&#039;&#039;&#039;&#039;&#039; an&lt;br /&gt;
&lt;br /&gt;
*Dann muss man noch unter &#039;&#039;&#039;&#039;&#039;Debug -&amp;gt; Interfaces -&amp;gt; Settings&#039;&#039;&#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;Vector table start&#039;&#039;&#039;&#039;&#039; auf 0x20000000 ändern und &#039;&#039;&#039;&#039;&#039;Execute from RAM&#039;&#039;&#039;&#039;&#039; auswählen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:bootsram_1.png Booten aus dem SRAM]] [[Datei:bootsram_2.png Booten aus dem SRAM]]&lt;br /&gt;
&lt;br /&gt;
Anschließend kann man die Anwendung ganz normal debuggen. Nach einem Reset muss die Anwenung erneut mit dem Debugger gestartet werden.&lt;br /&gt;
&lt;br /&gt;
=Fortsetzung folgt..=&lt;br /&gt;
Kritik, Wünsche usw. sind gerne erwünscht, am besten hier in den Thread posten: [http://www.mikrocontroller.net/topic/323750 Neues STM32 Tutorial]&lt;br /&gt;
&lt;br /&gt;
[[Category:ARM]]&lt;br /&gt;
[[Category:STM32]]&lt;/div&gt;</summary>
		<author><name>Avrprogger</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=STM32_-_Einstieg_mit_Em::Blocks&amp;diff=82099</id>
		<title>STM32 - Einstieg mit Em::Blocks</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=STM32_-_Einstieg_mit_Em::Blocks&amp;diff=82099"/>
		<updated>2014-03-18T20:30:53Z</updated>

		<summary type="html">&lt;p&gt;Avrprogger: usb&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In diesem Tutorial werde ich versuchen, möglichst einfach, die ersten Schritte zur Entwicklung von STM32 Anwenungen mit der Em::Blocks IDE zu erklären. Hier soll nicht so stark auf die einzelnen Peripherie-Module der Controller eingegangen werden, sondern mehr auf die IDE und die verschieden Libraries, wie die CMSIS Library, die DSP-Library, die Standard-Peripheral-Library, die USB-Library und vllt. über Ethernet. Ich denke ein Kapitel zu FreeRTOS wird es auch geben. Auserdem steht im Vordergrund Sachen wie z.B. booten aus dem SRAM, In-Application-Programming, FPU, Core-Coupled-RAM usw. Mal sehn wie weit ich komme ;)&lt;br /&gt;
&lt;br /&gt;
==Die Entwicklungsumgebung==&lt;br /&gt;
===Hardware===&lt;br /&gt;
Zum testen der Anwendungen, benutze ich das STM32F4-Discovery Board, welches einen Debugger, Peripherie und natürlich einen STM32 Controller (STM32F407VGT6) enthält. Deshalb sind alle Beispiele hier für den STM32F407VG Controller ausgelegt, können aber meisten 1:1 auf andere Controller portiert werden. Ich werde auch möglichsts keine STM32F4-Discovery Board spezifischen Libraries verwenden, damit der Portierungs-Vorgang möglichsts einfach bleibt.&lt;br /&gt;
&lt;br /&gt;
===Software===&lt;br /&gt;
In diesem Tutorial verwende ich [http://www.emblocks.org/ Em::Blocks] als IDE. Em::Blocks ist eine kostenlose, uneingeschränkte IDE, die alle STM32 Mikrcontroller unterstützt und sehr einfach zu bedienen ist.&lt;br /&gt;
nach dem Download kann die IDE per Dialog, sehr einfach, installiert werden. Als Compiler beinhaltet Em::Blocks den &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
Die IDE unterstützt zurzeit den ST-Link, den J-Link und es gibt eine Generic-Vorlage, durch welche andere Debugger konfiguriert werden können.&lt;br /&gt;
&lt;br /&gt;
Außerdem muss noch der passende Treiber für den Debugger installiert werden. Verwendet man ein Discovery-Board muss der [http://www.st.com/web/catalog/tools/FM146/CL1984/SC724/SS1677/PF251168 ST-Link/V2]-Treiber heruntergeladen und installiert werden. (Die Installation muss evtl. als Administrator ausgeführt werden, da sonst die Installation unvollständig wird.) Nach der Installation des Treibers kann man den Debugger über die entsprechende USB Schnittstelle an den PC anschließen und es sollte die Meldung von Windows kommen, dass der richtige Treiber gefunden wurde.&lt;br /&gt;
&lt;br /&gt;
===Libraries===&lt;br /&gt;
Zum programmieren benötigt man noch die [http://www.arm.com/products/processors/cortex-m/cortex-microcontroller-software-interface-standard.php CMSIS] und die Standard-Peripheral-Library (z.B. für die F4 Controller [http://www.st.com/stonline/stappl/productcatalog/app?page=partNumberSearchPage&amp;amp;levelid=SS1577&amp;amp;parentid=1743&amp;amp;resourcetype=SW Standard-Peripheral-Library-F4]), die man am besten in einen Ordner (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\STM32&#039;&#039;&#039;&#039;&#039;) entpackt&lt;br /&gt;
&lt;br /&gt;
==Basis-Wissen zur IDE==&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von Dateien zum Projekt===&lt;br /&gt;
Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf &amp;lt;ProjektName&amp;gt; -&amp;gt; Add files...&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Enfernen von Dateien aus dem Projekt===&lt;br /&gt;
Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf die Datei / mehrere Dateien auswählen -&amp;gt; Remove file from project&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
Die Dateien werden lediglich aus dem Projekt entfernt und nicht von der Festplatte gelöscht.&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von Include-Pfaden===&lt;br /&gt;
Sofern die Include-Datei(en) nicht im standard Include-Ordner &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; des Projektes liegen, muss man den Pfad zum Projekt hinzufügen, damit der Compiler die Include-Dateien später auch finden kann. Man geht wie folgt vor: Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; Search Directories -&amp;gt; Add&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von globalen Defines zum Build===&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; #defines&#039;&#039;&#039;&#039;&#039; können globale Defines hinzugefügt werden.&lt;br /&gt;
&lt;br /&gt;
===Compilieren===&lt;br /&gt;
Entweder über das &#039;&#039;&#039;&#039;&#039;Build&#039;&#039;&#039;&#039;&#039; Menü oder über &#039;&#039;&#039;&#039;&#039;F7&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Um eine genau Ausgabe des Compiler-Aufrufes mit allen Argumenten zu bekommen, geht man im &#039;&#039;&#039;&#039;&#039;Settings&#039;&#039;&#039;&#039;&#039; Menü auf &#039;&#039;&#039;&#039;&#039;Tools...&#039;&#039;&#039;&#039;&#039; und dann auf &#039;&#039;&#039;&#039;&#039;Toolchain executables&#039;&#039;&#039;&#039;&#039;. Ganz unten, unter &#039;&#039;&#039;&#039;&#039;Logging&#039;&#039;&#039;&#039;&#039; kann man dann &#039;&#039;&#039;&#039;&#039;Full command line&#039;&#039;&#039;&#039;&#039; auswählen.&lt;br /&gt;
&lt;br /&gt;
====Compiler Optionen====&lt;br /&gt;
=====Optimierung=====&lt;br /&gt;
Standardmäßig verwendet Em::Blocks keine Optimierung. Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; Categories: Optimization&#039;&#039;&#039;&#039;&#039; kann zwischen verschieden Optimierungen ausgewählt werden.&lt;br /&gt;
&lt;br /&gt;
=====Verschiedene C-Standards=====&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; Categories: Language standard&#039;&#039;&#039;&#039;&#039; kann man zwischen verschieden C-Standard auswählen, wie z.B, C99.&lt;br /&gt;
(Mit C99 können auch die Lauf-Variable in der for-Schleife deklariert werden: for(int i;..))&lt;br /&gt;
&lt;br /&gt;
===Debuggen===&lt;br /&gt;
*Als erstes den Debugger starten über das &#039;&#039;&#039;&#039;&#039;Debug&#039;&#039;&#039;&#039;&#039; Menü und &#039;&#039;&#039;&#039;&#039;Start/stop Debug Session&#039;&#039;&#039;&#039;&#039; oder über &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
*Danach läuft die Anwendung auf dem Controller und warten im &#039;&#039;&#039;&#039;&#039;Reset_Handler&#039;&#039;&#039;&#039;&#039; auf Einzelschritt- bzw. Run- Befehle (&#039;&#039;&#039;&#039;&#039;F5, F10, F11&#039;&#039;&#039;&#039;&#039; usw..(siehe &#039;&#039;&#039;&#039;&#039;Debug-Menü&#039;&#039;&#039;&#039;&#039; für alle Möglichkeiten))&lt;br /&gt;
&lt;br /&gt;
*Mit &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039; wird die Debug-Session auch wieder beendet&lt;br /&gt;
&lt;br /&gt;
*Unter &#039;&#039;&#039;&#039;&#039;Debug -&amp;gt; Interfaces -&amp;gt; Target settings&#039;&#039;&#039;&#039;&#039; können Eigenschaften, wie z.B &#039;&#039;&#039;&#039;&#039;Run to main()&#039;&#039;&#039;&#039;&#039; aktiviert werden.&lt;br /&gt;
&lt;br /&gt;
====Register View====&lt;br /&gt;
Damit man beim Debuggen sich bequem die Werte der Register (der Peripherie-Register) ansehen kann, bracht man eine, zum Controller passende &#039;&#039;&#039;&#039;&#039;System View Description&#039;&#039;&#039;&#039;&#039;-Datei (*.svd), die die verschiedenen Register beschreibt (Name, Adresse, usw..). In Em::Blocks gibt es dazu ein Tool, womit man solche Dateien herunterladen und verwenden kann.&lt;br /&gt;
&lt;br /&gt;
Um sich die nur die Core-Register anzusehen / zu bearbeiten braucht man keine SVD-Datei.&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;&#039;&#039;&#039;Debug&#039;&#039;&#039;&#039;&#039; -&amp;gt; &#039;&#039;&#039;&#039;&#039;Plugins&#039;&#039;&#039;&#039;&#039; -&amp;gt; &#039;&#039;&#039;&#039;&#039;SVD repository&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Controller-Hersteller und Cntroller-Reihe auswählen&lt;br /&gt;
*Speicherort auswählen (Standard ist das aktuelle Projekt-Verzeichniss)&lt;br /&gt;
*Wenn das Häkchen bei &#039;&#039;&#039;&#039;&#039;Set and launch target debug configuration&#039;&#039;&#039;&#039;&#039; gesetzt ist, öffnen sich die Debug-Einstellungen automatisch, und das neue SVD-File wird verwenden.&lt;br /&gt;
*Debug-Einstellungen mit &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; schließen&lt;br /&gt;
&lt;br /&gt;
===Projekt als Template abspeichern===&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;File -&amp;gt; Save project as template...&#039;&#039;&#039;&#039;&#039;. Das Template erscheint dann im Projekt-Dialog unter &#039;&#039;&#039;&#039;&#039;User templates&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Das erste Projekt erstellen==&lt;br /&gt;
Hier erkläre ich, wie man am Besten (aus meiner Sicht), ein neues Projekt von Grund auf erstellt, sodass man hinterher, den Controller-Kern über die CMSIS-Library und die Peripherie über die Register steuern kann.&lt;br /&gt;
&lt;br /&gt;
===1. Projekt mit der IDE erstellen===&lt;br /&gt;
Nach der Installation der oben beschriebenen Komponenten erstellt man am besten ein Verzeichnis (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\EmBlocks&#039;&#039;&#039;&#039;&#039;), indem später alle Projekte gespeichert werden. Für Libraries kann man auch noch ein Verzeichnis (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\STM32&#039;&#039;&#039;&#039;&#039;) erstellen, wo alle Libraries gespeichert werden, die man für die Projekt brauchen.&lt;br /&gt;
&lt;br /&gt;
Als nächstes starten man EmBlocks. Bei dem ersten Start öffnet sich ein Fenster, wo verschiedene Compiler angezeigt werden, die Em::Blocks findet. Dort wählt man den &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039; aus und klickt &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039;. Nun sollte sich das Hauptfenster von Em::Blocks öffnen. Über &#039;&#039;&#039;&#039;&#039;Create a new Project&#039;&#039;&#039;&#039;&#039; oder &#039;&#039;&#039;&#039;&#039;File -&amp;gt; New -&amp;gt; Project&#039;&#039;&#039;&#039;&#039; ruft man den Projekt-Dialog auf und kann ein neues Projekt erzeugen.&lt;br /&gt;
&lt;br /&gt;
Auf der Ersten Seite wählen man den &#039;&#039;&#039;&#039;&#039;STmicro-ARM&#039;&#039;&#039;&#039;&#039; Projekt-Typ aus.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_1.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auf der nächsten Seite wird man darauf hingewiesen, dass das der entsprechende Projekt-Typ-Dialog ausgeführt wird. Hier kann man ein Häkchen bei &#039;&#039;&#039;&#039;&#039;Skip this page next time&#039;&#039;&#039;&#039;&#039; setzen und auf &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; klicken.&lt;br /&gt;
&lt;br /&gt;
Im nächsten Schritt wählen man das zuvor erstellt Verzeichnis unter &#039;&#039;&#039;&#039;&#039;Folder to create Project in&#039;&#039;&#039;&#039;&#039; aus, indem später alle Projekt gespeichert werden. Außerdem geben wir dem Projekt einen Namen (z.B. &#039;&#039;&#039;&#039;&#039;FirstProject&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_2.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danach muss man einen Compiler auswählen und bestimmen, welche Projekt-Konfigurationen erszeugt werden sollen. Unter &#039;&#039;&#039;&#039;&#039;Compiler&#039;&#039;&#039;&#039;&#039; wählt man &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039; und man kann das Häkchen bei &#039;&#039;&#039;&#039;&#039;Create &amp;quot;Release&amp;quot; configuration&#039;&#039;&#039;&#039;&#039; entfernen, da diese unnötig ist, die Debug-Konfiguration sollte eig. immer ausreichen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_3.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auf den folgenden Seite wird der Controller ausgewählt. Verwendet man ein STM32F4-Discovery Board müssen folgende Dinge gewählt werden: &#039;&#039;&#039;&#039;&#039;Cortex_M4 (F3xx - F4xx) -&amp;gt; STM32F4xx (Cortex M4 with FPU) -&amp;gt; STM32F407VG&#039;&#039;&#039;&#039;&#039;. Leider sind die Auswahl Möglichkeiten nicht ganz richtig, da auch die F3 Controller einen Cortex M4 Kern und eine FPU haben (Ist aber nicht so wichtig, ist nur eine formale Sache). Außerdem entfernt man das Häkchen bei &#039;&#039;&#039;&#039;&#039;Standard Peripherals Library&#039;&#039;&#039;&#039;&#039; (Wie man die Standard-Peripheral-Library einbindet und verwendet erkläre ich später). Man kann auch das Häkchen bei &#039;&#039;&#039;&#039;&#039;Create hex file for Realease target&#039;&#039;&#039;&#039;&#039; entfernen.&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;Stack Size&#039;&#039;&#039;&#039;&#039; und &#039;&#039;&#039;&#039;&#039;Heap Size&#039;&#039;&#039;&#039;&#039; wird die Größe von Stack und Heap festgelegt. Für eine erste Anwendung kann man die Einstellungen so lassen (Stack-Size: 0x0100 =&amp;gt; 256 Byte Stack und Heap-Size: 0x0000 =&amp;gt; kein Heap). Mit &#039;&#039;&#039;&#039;&#039;Finish&#039;&#039;&#039;&#039;&#039; ist der Projekt Dialog abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_4.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danach sollten sich zwei neue Fenster öffnen, um die Debug-Eigenschaften fest zu legen.&lt;br /&gt;
Verwendet man ein Discovery Board/ST-Link müssen die Einstellungen wie auf dem Bild gewählt werden. Über den Button &#039;&#039;&#039;&#039;&#039;Settings&#039;&#039;&#039;&#039;&#039; öffnet sich das zweite Fenster, falls sich dieses nicht schon von alleine öffnen sollte. Nach den Schließen der Fenster über &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; ist der Projekt Dialog beendet und ein neues Projekt steht zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_5_1.png|Debug Eigenschaften 1. Fenster]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_5_2.png|Debug Eigenschaften 2. Fenster]]&lt;br /&gt;
&lt;br /&gt;
===2. CMSIS-Library und Startup-Code hinzufügen===&lt;br /&gt;
Wenn man sich, nachdem man ein neues Projekt in der IDE erstellt hat, die bereits vorhandenen Dateien im Projekt ansieht, stellt man fest, das bereits ein Ordner &#039;&#039;&#039;&#039;&#039;cmsis&#039;&#039;&#039;&#039;&#039; existiert, der einige wichtige Include-Dateien der CMSIS-Library enthält. Allerdings sind das wirklich nur die wichtigsten Include-Dateien der CMSIS-Library und dazu noch, die aus einer älternen Version. Ich ziehe es deshalb vor die &amp;quot;Mini-CMSIS-Libraray&amp;quot; und die &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c/.h&#039;&#039;&#039;&#039;&#039; Dateien des Projektes durch aktuellere Versionen zu ersetzen. So ist später auch die Integration  von anderen Libraries, wie z.B. der CMSIS-DSP-Libarary einfacher.  &lt;br /&gt;
&lt;br /&gt;
Zunächst gehen man in das Projekt-Verzeichnis und löscht:&lt;br /&gt;
*Den Ordner &#039;&#039;&#039;&#039;&#039;cmsis&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Alle Dateien im Include Verzeichnis &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; im &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner&lt;br /&gt;
&lt;br /&gt;
Außerdem entfernt man auch alle gelöschten Dateien in der IDE aus dem Projekt mit &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Rechts Klick -&amp;gt; Remove file from project&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Es sollte folgende Verzeichnis Struktur überbleiben:&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_6.png|Überbleibende Dateien]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Jetzt müssen die gelöschten Dateien durch die aktuelleren ersetzt werden.&lt;br /&gt;
&lt;br /&gt;
*Dazu kopieren man den gesamten Ordner &#039;&#039;&#039;&#039;&#039;CMSIS&#039;&#039;&#039;&#039;&#039; aus dem CMSIS Download in das Projekt Verzeichnis.&lt;br /&gt;
&lt;br /&gt;
*Aus dem Standard-Peripheral-Library Download kopiert man von &#039;&#039;&#039;&#039;&#039;Libraries\CMSIS\Device\ST\STM32F4xx\Include&#039;&#039;&#039;&#039;&#039; alle Dateien in den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projekt Verzeichnisses&lt;br /&gt;
&lt;br /&gt;
*Aus der Standard-Peripheral-Library kopieren man ebenfalls von &#039;&#039;&#039;&#039;&#039;Libraries\CMSIS\Device\ST\STM32F4xx\Source\Templates&#039;&#039;&#039;&#039;&#039; die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; in den &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner des Projekts&lt;br /&gt;
&lt;br /&gt;
Anschließend müssen die neuen Dateien in der IDE dem Projekt hinzugefügt werden. Dazu benutzt man &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Rechts Klick -&amp;gt; Add files&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
*Aus dem &#039;&#039;&#039;&#039;&#039;CMSIS&#039;&#039;&#039;&#039;&#039; Ordner im Projekt Verzeichnis werden aus den Unterorder &#039;&#039;&#039;&#039;&#039;Include&#039;&#039;&#039;&#039;&#039; folgende Dateien dem Projekt hinzugefügt:&lt;br /&gt;
**arm_common_tables.h&lt;br /&gt;
**arm_const_structs.h&lt;br /&gt;
**arm_math.h&lt;br /&gt;
**core_cm4.h&lt;br /&gt;
**core_cm4_simd.h&lt;br /&gt;
**core_cmFunc.h&lt;br /&gt;
**core_cmInstr.h&lt;br /&gt;
*Alle Dateien aus den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projektes&lt;br /&gt;
*Die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; aus dem &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner&lt;br /&gt;
&lt;br /&gt;
So sollte die Struktur dann aussehen:&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_7.png|Anwenungs-Grundgerüst]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Da einige Dateien der Libraries später bearbeitet werden müssen und Schreibgeschützt sind, weise ich hier schonmal darauf hin, das der Schreibschutz in der IDE über &#039;&#039;&#039;&#039;&#039;Rechts Klick auf die Datei -&amp;gt; Properties -&amp;gt; Häkchen bei &amp;quot;File is read only&amp;quot; entfernen&#039;&#039;&#039;&#039;&#039; entfert werden kann.&lt;br /&gt;
&lt;br /&gt;
Damit die IDE die Header-Dateien der CMSIS Library auch finden kann, weil diese ja nicht im standard Include Ordner &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; liegen, muss unter &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Build Options -&amp;gt; Search Directories&#039;&#039;&#039;&#039;&#039; der Pfad &#039;&#039;&#039;&#039;&#039;CMSIS\Include&#039;&#039;&#039;&#039;&#039; hinzugefügt werden.&lt;br /&gt;
&lt;br /&gt;
Compiliert man jetzt das Projekt mit &#039;&#039;&#039;&#039;&#039;F7&#039;&#039;&#039;&#039;&#039; gibt es ein paar Fehler Meldungen, weil keine Controller-Reihe ausgewählt wurde. Ebenfalls unter &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Build Options -&amp;gt; Compiler Settings -&amp;gt; #defines&#039;&#039;&#039;&#039;&#039; wird der Define &#039;&#039;&#039;&#039;&#039;STM32F40_41xxx&#039;&#039;&#039;&#039;&#039; hinzugefügt.&lt;br /&gt;
&lt;br /&gt;
Beim erneuten Compilieren sollten sich nun keine neuen Fehler ergeben.&lt;br /&gt;
&lt;br /&gt;
===3. Das erste Programm===&lt;br /&gt;
Nachdem ein grundsätzliches &amp;quot;Gerüst&amp;quot; fertig ist, kann man den ersten Code schreiben.&lt;br /&gt;
main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC-&amp;gt;AHB1ENR |= RCC_AHB1ENR_GPIODEN;    //Takt für GPIO aktivieren&lt;br /&gt;
    GPIOD-&amp;gt;MODER |= GPIO_MODER_MODER15_0;   //GPIOD Pin15 als Ausgang&lt;br /&gt;
    GPIOD-&amp;gt;BSRRL |= GPIO_BSRR_BS_15;        //GPIOD Pin15 auf High ziehen&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039; wird dann der Debugger gestartet. Hat der Debugger das Projekt erfolgreich übertragen kann die Ausführung mit &#039;&#039;&#039;&#039;&#039;F5&#039;&#039;&#039;&#039;&#039; begonnen werden.&lt;br /&gt;
&lt;br /&gt;
==Libraries einbinden/verwenden==&lt;br /&gt;
Um Libraries, wie hier im Tutorial, einzubinden, wird ein existierendes Projekt, wie ein im Kapitel [http://www.mikrocontroller.net/articles/STM32_-_Einstieg_mit_Em::Blocks#Das_erste_Projekt_erstellen Das Erste Projekt erstellen] beschrieben wird, vorausgesetzt.&lt;br /&gt;
&lt;br /&gt;
===Einbinden der Standard-Peripheral-Library===&lt;br /&gt;
Um nicht immer die einzelnen Register, wie im ersten &amp;quot;bare-metal&amp;quot; Beispiel, aus dem Reference-Manual zu suchen und zu beschreiben, gibt es von ST die Standard Peripheral Library, die diese Aufgaben übernimmt und mit der sich die &amp;quot;normale/grundlegende&amp;quot; (Alles außer USB und Ethernet) Peripherie recht einfach steuern lässt. Ich kopiere die Standard-Peripheral-Library immer per Hand in das Projekt. Darduch hat man auch gleich die aktuellste Version (in den älteren Version gibt es einige Bugs). &lt;br /&gt;
&lt;br /&gt;
*1. Den Ordner &#039;&#039;&#039;&#039;&#039;Libraries\STM32F4xx_StdPeriph_Driver&#039;&#039;&#039;&#039;&#039; aus dem Standard-Peripheral-Library Download in das Projekt-Verzeichnis kopieren&lt;br /&gt;
*2. Die Datei &#039;&#039;&#039;&#039;&#039;Project\STM32F4xx_StdPeriph_Templates\stm32f4xx_conf.h&#039;&#039;&#039;&#039;&#039; ebenfalls aus dem Standard-Peripheral-Library Download in den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projektes kopieren.&lt;br /&gt;
*3. In der IDE den Include-Path &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\inc&#039;&#039;&#039;&#039;&#039; hinzufügen&lt;br /&gt;
*4. Und das/den Define &#039;&#039;&#039;&#039;&#039;USE_STDPERIPH_DRIVER&#039;&#039;&#039;&#039;&#039; hinzufügen&lt;br /&gt;
*4. Source- und Include-Dateien zum Projekt hinzufügen&lt;br /&gt;
**Achtung: Es dürfen nur die Dateien hinzugefügt werden, für die der Controller auch die entsprechende Peripherie bereit stellt. Diese Dateien dürfen nicht beim STM32F4-Discovery/STM32F407VG hinzugefügt werden.&lt;br /&gt;
***stm32f4xx_dma2d.c/.h&lt;br /&gt;
***stm32f4xx_fmc.c/.h&lt;br /&gt;
***stm32f4xx_ltdc.c/.h&lt;br /&gt;
***stm32f4xx_sai.c/.h&lt;br /&gt;
&lt;br /&gt;
Daraus resultiert folgende Struktur:&lt;br /&gt;
&lt;br /&gt;
[[Datei:stdperiphlib_2.png|Header-Struktur]] [[Datei:stdperiphlib_1.png|Source-Struktur]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Anschließen kann die Standard-Peripheral-Library benutz werden.&lt;br /&gt;
main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);&lt;br /&gt;
&lt;br /&gt;
    GPIO_InitTypeDef GPIOD_InitStructure;&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Mode = GPIO_Mode_OUT;     //Als Ausgang&lt;br /&gt;
    GPIOD_InitStructure.GPIO_OType = GPIO_OType_PP;    //Push-Pull Betrieb&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Pin = GPIO_Pin_15;        //Pin 15 (STM32F4-Discovery: Blaue LED)&lt;br /&gt;
    GPIOD_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;  //Kein Pull-Up oder Pull-Down Widerstand aktiviert&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Speed = GPIO_Speed_25MHz; //25MHz Update-Rate&lt;br /&gt;
    GPIO_Init(GPIOD, &amp;amp;GPIOD_InitStructure);&lt;br /&gt;
&lt;br /&gt;
    GPIO_SetBits(GPIOD, GPIO_Pin_15);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hier ist noch ein &amp;quot;BasicFramework&amp;quot;, dass die komplette CMSIS- und Standard-Peripheral-Library enthält und kann Quasi als Basis für alle Projekte verwendet werden. Allerdings ist das Framework primär auf die STM32F405/7 und STM32F415/7 ausgelegt. Die neueren STM32F401, STM32F42X und STM32F43X  haben noch etwas andere Peripherie, dass Framework müsste dann entsprechend angepasst werden. Download: [[Datei:StdPeriphDriver_BasicFramework.zip]]&lt;br /&gt;
&lt;br /&gt;
===Einbinden der DSP-Library===&lt;br /&gt;
STM32F3 / STM32F4 Microcontroller haben neben der FPU noch einen Digital-Signal-Processor (DSP). Die DSP dient hauptsächlich dazu, viele Daten schnell zu verarbeiten (z.B. Video- oder Audiosignal). Der CMSIS-Download beinhaltet dazu neben der eigentlichen CMSIS-Library auch noch eine DSP-Library. Diese Library stellt sowohl einfache, mathematische Funktionen wie addieren, multiplizieren usw. als auch komplexe Funktionen, wie z.B  einen IIR-Filter, zur Verfügung. Die DSP-Library ist weiter aufgeteilt in kleinere Module, wie z.B. BasicMathFunctions, FilteringFunctions usw. (siehe &#039;&#039;&#039;&#039;&#039;CMSIS\DSP-Library\Source&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
*1. Source-Dateien des benötigten Moduls zum Projekt hinzufügen. (&#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Add files...&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
*2. &#039;&#039;&#039;&#039;&#039;arm_math.h&#039;&#039;&#039;&#039;&#039; in der &#039;&#039;&#039;&#039;&#039;main.c&#039;&#039;&#039;&#039;&#039; einbinden&lt;br /&gt;
*3. Damit die Warnung &amp;quot;Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)&amp;quot; verschwindet, muss der Define &#039;&#039;&#039;&#039;&#039;__FPU_PRESENT&#039;&#039;&#039;&#039;&#039; hinzugefügt werden. (Keine Ahnung, wieso es die Warnung gibt)&lt;br /&gt;
 &lt;br /&gt;
Jetzt kann die DSP-Library verwedet werden. Das Beispiel multipliziert zwei Buffer miteinander. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
#include &amp;quot;arm_math.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    float32_t x[1024];&lt;br /&gt;
    float32_t y[1024];&lt;br /&gt;
    float32_t z[1024];&lt;br /&gt;
&lt;br /&gt;
    for(uint16_t i = 0; i &amp;lt; 1024; i++)&lt;br /&gt;
    {&lt;br /&gt;
        x[i] = i;&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for(uint16_t i = 0; i &amp;lt; 1024; i++)&lt;br /&gt;
    {&lt;br /&gt;
        y[i] = PI;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    arm_mult_f32(x, y, z, 1024);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Startup-Code, Linker-Script, Takt, FPU usw.==&lt;br /&gt;
===Startup-Code===&lt;br /&gt;
Em::Blocks fügt standardmäßig einen Startup-Code mit in das Projekt ein. Die wichtigsten Dinge die darin erledigt werden sind folgende:&lt;br /&gt;
&lt;br /&gt;
*Stack und Heap wird angelgt&lt;br /&gt;
*Die Vector-Table wird angelegt&lt;br /&gt;
*Ein Default Reset-Handler wird implementiert, dieser erledigt folgende aufgaben:&lt;br /&gt;
**Kopieren der definierten Daten aus dem Flash in den SRAM&lt;br /&gt;
**&#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; wird aufgerufen, wenn &#039;&#039;&#039;&#039;&#039;__NO_SYSTEM_INIT&#039;&#039;&#039;&#039;&#039; nicht definiert ist&lt;br /&gt;
**Sprung in die &#039;&#039;&#039;&#039;&#039;main()&#039;&#039;&#039;&#039;&#039; Funktion&lt;br /&gt;
*Allen anderen Interrupt-Handler wird eine Default-Funktion &#039;&#039;&#039;&#039;&#039;def_irq_handler&#039;&#039;&#039;&#039;&#039; mit einer &#039;&#039;&#039;&#039;&#039;while(1)&#039;&#039;&#039;&#039;&#039;-Schleife zugewiesen, falls kein anderer Interrupt-Handler existiert.&lt;br /&gt;
&lt;br /&gt;
Normalerweise muss am Startup-Code nichts verändert werden.&lt;br /&gt;
&lt;br /&gt;
===Linker-Script===&lt;br /&gt;
Em::Blocks stellt zwei fertige Linker-Scripts bereit, eins für die Ausführung des Programmes aus dem Flash (&#039;&#039;&#039;&#039;&#039;*_flash.ld&#039;&#039;&#039;&#039;&#039;), das andere für die Ausführung aus dem SRAM (&#039;&#039;&#039;&#039;&#039;*_sram.ld&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Normalerweise muss auch hier nichts geändert werden, es sei den Daten sollen in bestimmten Adressbereichen abgelegt werden (z.B. im Core-Coupled RAM), was ich später noch zum Tutorial hinzufüge.&lt;br /&gt;
&lt;br /&gt;
===Der Takt===&lt;br /&gt;
Jeder Controller oder Prozessor braucht einen Takt, indem er die einzelnen Maschinen-Befehle abarbeiten kann.&lt;br /&gt;
Bei den STM32 Mikrocontrollern kann dieser Takt aus verschiedenen Quellen kommen:&lt;br /&gt;
&lt;br /&gt;
1. High Speed Internal Oszillator (HSI)&lt;br /&gt;
&lt;br /&gt;
2. High Speed External Oszillator (HSE)&lt;br /&gt;
&lt;br /&gt;
3. Low Speed Internal Oszillator (LSI)&lt;br /&gt;
&lt;br /&gt;
4. Low Speed External Oszillator (LSE)&lt;br /&gt;
&lt;br /&gt;
5. Phase-Locked Loop (PLL) (generiert den Takt aus den ersten vier Taktquellen durch Teiler und Faktoren)&lt;br /&gt;
&lt;br /&gt;
Nach einem Reset wird der Controller aus der HSI Taktquelle versorgt (16MHz beim STM32F407VG). Um die voll Performance des Controllers zu erreichen muss die PLL verwendet werden, welche den Takt durch geschickte Teiler und Faktoren vervielfältigt, sodass am Ende der Controller mit der maximalen Taktfrequenz läuft. Die notwendige Initialisierung der PLL findet in der Funktion &#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; statt. Die PLL erzeugt zunächst einen Basistakt:&lt;br /&gt;
&lt;br /&gt;
PLL_VCO = (F_HSE / PLL_M) * PLL_N&lt;br /&gt;
&lt;br /&gt;
Aus diesem Takt wird dann der Takt für den Controller-Kern abgeleitet:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = PLL_VCO / PLL_P&lt;br /&gt;
&lt;br /&gt;
Und der Takt für SDIO / USB / RNG (48MHz):&lt;br /&gt;
&lt;br /&gt;
48MHz = PLL_VCO / PLL_Q&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Durch weiter Teiler werden, die Takte für die einzelnen Busse erzeugt, da diese nicht alle beliebig schnell betrieben werden dürfen.&lt;br /&gt;
&lt;br /&gt;
Genaue Angaben findet man zu dem jeweiligen Clock-System des Controllers im Reference Manual.&lt;br /&gt;
&lt;br /&gt;
Ein Blick in den &amp;quot;Kommentar-Header&amp;quot; verrät, dass von einem externen (HSE) Oszillator von 25MHz ausgegangen wird, der die PLL versorgen soll.&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((25MHz / PLL_M(25)) * PLL_N(336)) / PLL_P(2) = 168MHz&lt;br /&gt;
&lt;br /&gt;
Allerdings stimmt diese Rechnung natürlich nur, wenn wirklich ein 25MHz Quarz am Controller angeschlossen ist. Auf dem STM32F4-Discovery Board befindet sich aber nur ein 8MHz Quarz. Demnach gilt:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((8MHz / PLL_M(25)) * PLL_N(336)) / PLL_P(2) = 53.76MHz&lt;br /&gt;
&lt;br /&gt;
Der Controller läuft also nur mit 53.76MHz, wenn wie ober beschrieben ein Projekt erstellt wird. Allerdings kann dieses Problem durch ändern von den betroffen Defines behoben werden:&lt;br /&gt;
 &lt;br /&gt;
*Dazu geht man in die &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; Datei und passt zur Vollständigkeit erstmal die zum Controller passende Tabelle im &amp;quot;Kommentar-Header&amp;quot; an (Z.57f):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      HSE Frequency(Hz)                      | 8000000&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      PLL_M                                  | 8&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Danach passt man den PPL_M Define (Z.254) an:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/************************* PLL Parameters *************************************/&lt;br /&gt;
/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */&lt;br /&gt;
#define PLL_M      8&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Außerdem muss man den HSE_VALUE Define in der &#039;&#039;&#039;&#039;&#039;inc/stm32f4xx.h&#039;&#039;&#039;&#039;&#039; angepasst werden (Z.122):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#if !defined  (HSE_VALUE)&lt;br /&gt;
  #define HSE_VALUE    ((uint32_t)8000000) /*!&amp;lt; Value of the External oscillator in Hz */&lt;br /&gt;
&lt;br /&gt;
#endif /* HSE_VALUE */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine neue Berechnung zeigt:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((8MHz / PLL_M(8)) * PLL_N(336)) / PLL_P(2) = 168MHz&lt;br /&gt;
&lt;br /&gt;
Jetzt läuft der Controller mit maximaler Geschwindigkeit.&lt;br /&gt;
&lt;br /&gt;
Die Theorie wird durch folgendes Programm verifiziert. Der geviertelte System-Takt SYSCLK wir am Pin PC9 ausgegeben. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);&lt;br /&gt;
&lt;br /&gt;
    GPIO_InitTypeDef GPIOC_InitStructure;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Mode = GPIO_Mode_AF;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_OType = GPIO_OType_PP;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Pin = GPIO_Pin_9;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;&lt;br /&gt;
    GPIO_Init(GPIOC, &amp;amp;GPIOC_InitStructure);&lt;br /&gt;
&lt;br /&gt;
    RCC_MCO2Config(RCC_MCO2Source_SYSCLK, RCC_MCO2Div_4);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Die FPU===&lt;br /&gt;
====Allgemeines====&lt;br /&gt;
STM32F3 und STM32F4 Controller haben eine FPU.&lt;br /&gt;
Damit die FPU richtig verwendet wird, müssen normalerweise zwei Bedingungen erfüllt sein:&lt;br /&gt;
&lt;br /&gt;
1. Der Controller muss die FPU Hardware-seitig aktivieren&lt;br /&gt;
&lt;br /&gt;
2. Damit die FPU auch was zu tuen bekommt, müssen vom Compiler FPU-Instructions erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
Die Em::Blocks IDE verwendet standardmäßig die FPU, wenn eine Vorhanden ist. Hier wird die FPU Hardware-seitig aktiviert (&#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; Z.341):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* FPU settings ------------------------------------------------------------*/&lt;br /&gt;
  #if (__FPU_PRESENT == 1) &amp;amp;&amp;amp; (__FPU_USED == 1)&lt;br /&gt;
    SCB-&amp;gt;CPACR |= ((3UL &amp;lt;&amp;lt; 10*2)|(3UL &amp;lt;&amp;lt; 11*2));  /* set CP10 and CP11 Full Access */&lt;br /&gt;
  #endif&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
__FPU_PRESENT wird in der &#039;&#039;&#039;&#039;&#039;stm32f4xx.h&#039;&#039;&#039;&#039;&#039; definiert.&lt;br /&gt;
__FPU_USED wird von der IDE übernommen (siehe Build-Log): &#039;&#039;&#039;&#039;&#039;-D__FPU_USED&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Außerdem wird der Compiler von der IDE standardmäßig mit dem Argument &#039;&#039;&#039;&#039;&#039;-mfloat-abi=hard&#039;&#039;&#039;&#039;&#039; aufgerufen, wodurch FPU-Instructions erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
====FPU abschalten====&lt;br /&gt;
Um die FPU ab zu schalten (Mir würde jetzt nur Strom sparen als Grund einfallen) geht man wie folgt vor:&lt;br /&gt;
&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; Device -&amp;gt; Policy&#039;&#039;&#039;&#039;&#039; wählt man &#039;&#039;&#039;&#039;&#039;Use target settings&#039;&#039;&#039;&#039;&#039; und über nimmt die Einstellungen, die vorher dort eingetragen waren, allerdings lässt man das Feld &#039;&#039;&#039;&#039;&#039;FP-hardware&#039;&#039;&#039;&#039;&#039; frei.&lt;br /&gt;
&lt;br /&gt;
[[Datei:fpu_1.png|FPU Abschalten Schritt 1]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;Compiler Settings -&amp;gt; Policy&#039;&#039;&#039;&#039;&#039; wählt man dann &#039;&#039;&#039;&#039;&#039;Use target options only&#039;&#039;&#039;&#039;&#039;. Dann kann man unter &#039;&#039;&#039;&#039;&#039;Categories&#039;&#039;&#039;&#039;&#039; die Option &#039;&#039;&#039;&#039;&#039;ARM FPU architecture&#039;&#039;&#039;&#039;&#039; auswählen. Dort stehen dann drei Möglichkeiten für die FPU zur Verfügung:&lt;br /&gt;
&lt;br /&gt;
1. Software-FPU-Library für Gleitkomma-Berechnung verwenden - Keine FPU-Instructions werden generiert (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=soft&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
2. Eine Mischung aus Software- und Hardware-FPU wird verwendet (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=softfp&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
3. Hardware-FPU wird für Gleitkomma-Berechnungen verwendet (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=hard&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
[[Datei:fpu_2.png|FPU Abschalten Schritt 2]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Um die FPU ab zu schalten wählt man natürlich die erste Möglichkeit.&lt;br /&gt;
Bei der 2. und 3. Möglichkeit fügt die IDE auch den Define &#039;&#039;&#039;&#039;&#039;__FPU_USED&#039;&#039;&#039;&#039;&#039; hinzu. Bei Der ersten Möglichkeit nicht. Der Code muss also nicht verändert / auskommentiert werden.&lt;br /&gt;
&lt;br /&gt;
Um die FPU wieder zu aktivieren müssen alle Schritte wieder rückgängig gemacht werden.&lt;br /&gt;
&lt;br /&gt;
Am besten ist es einfach mal alle Möglichkeiten im Einzelschritt durch zu probieren. Dann stellt man schnell fest, ob die FPU aktiviert wir oder nicht. Ein Blick in den erweiterten &#039;&#039;&#039;&#039;&#039;Build-Log&#039;&#039;&#039;&#039;&#039; gibt auch schnell Aufschluss darüber, wie der Compiler aufgerufen wird (siehe Kapitel [http://www.mikrocontroller.net/articles/STM32_-_Einstieg_mit_Em::Blocks#Compilieren Compilieren]).&lt;br /&gt;
&lt;br /&gt;
====Test Programm für die FPU====&lt;br /&gt;
Hier ein kleines Testprogramm, dass misst wie viele Taktzyklen für eine Gleitkomma-Multiplikation gebraucht werden. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define CORE_SysTickEn()    (*((u32*)0xE0001000)) = 0x40000001&lt;br /&gt;
#define CORE_SysTickDis()   (*((u32*)0xE0001000)) = 0x40000000&lt;br /&gt;
#define CORE_GetSysTick()   (*((u32*)0xE0001004))&lt;br /&gt;
&lt;br /&gt;
uint32_t t1, t2, dt;&lt;br /&gt;
float x, y, z;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    x = 53.64f;&lt;br /&gt;
    y = 0.27f;&lt;br /&gt;
&lt;br /&gt;
    CORE_SysTickEn();&lt;br /&gt;
    t1 = CORE_GetSysTick();&lt;br /&gt;
&lt;br /&gt;
    z = x * y;&lt;br /&gt;
&lt;br /&gt;
    t2 = CORE_GetSysTick();&lt;br /&gt;
    CORE_SysTickDis();&lt;br /&gt;
&lt;br /&gt;
    dt = (t2 - t1) - 9; //9 Takt-Zyklen werden für die Messung gebraucht &lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Core-Coupled-RAM verwenden===&lt;br /&gt;
Auf den normale SRAM kann durch den Core und die verschiedenen DMA-Controller zugegriffen werden. Jedoch können Core und DMA nicht gleichzeitig auf den SRAM zugreifen. Deswegen gibt es einen zweiten kleinen RAM, den Core-Coupled-RAM (CCRAM), auf den nur vom Core zugegriffen werden kann und nicht von einem DMA-Controller. Der CCRAM ist über einen anderen Bus an dem Cortex angeschlossen. Daduch wird ermöglicht, dass der Core sinnvoll weiterarbeiten kann, wenn ein DMA-Controller Daten aus den &amp;quot;Haupt&amp;quot;-RAM ließt/schreibt, indem der Core Daten aus dem CCRAM verarbeitet. Um Daten in den CCRAM zu legen, geht man wie folgt vor:&lt;br /&gt;
&lt;br /&gt;
1. Eine neue Section im Linkerscript anlegen:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
Sections:&lt;br /&gt;
{&lt;br /&gt;
  ...&lt;br /&gt;
&lt;br /&gt;
  .ccram :&lt;br /&gt;
  {&lt;br /&gt;
    *(.ccram)&lt;br /&gt;
  } &amp;gt; CCRAM&lt;br /&gt;
&lt;br /&gt;
  ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Um die neue Section zu verwenden benutzt man diesen Define:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#define CCRAM __attribute__((section(&amp;quot;.ccram&amp;quot;)))&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
int CCRAM dataInCCRAM;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Beim Debuggen stellt man fest das die Variable an der Adresse 0x10000000 liegt, der ersten Adresse das CCRAM&#039;s.&lt;br /&gt;
&lt;br /&gt;
==Booten aus dem SRAM==&lt;br /&gt;
STM32 Controller haben die Möglichkeit Code aus dem Flash als auch aus dem SRAM auszuführen. Um eine Anwenung per Debugger in des SRAM zu laden sind nur wenige Schritte erforderlich:&lt;br /&gt;
&lt;br /&gt;
*Um das Linkerscript für den SRAM zu verwenden geht man zu: &#039;&#039;&#039;&#039;&#039;Build options... -&amp;gt; Device&#039;&#039;&#039;&#039;&#039; dort wählt man unter &#039;&#039;&#039;&#039;&#039;Policy&#039;&#039;&#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;Use target settings&#039;&#039;&#039;&#039;&#039; aus und übernimmt die vorherigen Einstellungen, nur unter &#039;&#039;&#039;&#039;&#039;Linker script*&#039;&#039;&#039;&#039;&#039; gibt man &#039;&#039;&#039;&#039;&#039;.\stm32f407vg_sram.ld&#039;&#039;&#039;&#039;&#039; an&lt;br /&gt;
&lt;br /&gt;
*Dann muss man noch unter &#039;&#039;&#039;&#039;&#039;Debug -&amp;gt; Interfaces -&amp;gt; Settings&#039;&#039;&#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;Vector table start&#039;&#039;&#039;&#039;&#039; auf 0x20000000 ändern und &#039;&#039;&#039;&#039;&#039;Execute from RAM&#039;&#039;&#039;&#039;&#039; auswählen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:bootsram_1.png Booten aus dem SRAM]] [[Datei:bootsram_2.png Booten aus dem SRAM]]&lt;br /&gt;
&lt;br /&gt;
Anschließend kann man die Anwendung ganz normal debuggen. Nach einem Reset muss die Anwenung erneut mit dem Debugger gestartet werden.&lt;br /&gt;
&lt;br /&gt;
==USB-Libraries verwenden==&lt;br /&gt;
&lt;br /&gt;
=Fortsetzung folgt..=&lt;br /&gt;
Kritik, Wünsche usw. sind gerne erwünscht, am besten hier in den Thread posten: [http://www.mikrocontroller.net/topic/323750 Neues STM32 Tutorial]&lt;br /&gt;
&lt;br /&gt;
[[Category:ARM]]&lt;br /&gt;
[[Category:STM32]]&lt;/div&gt;</summary>
		<author><name>Avrprogger</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=STM32_-_Einstieg_mit_Em::Blocks&amp;diff=82098</id>
		<title>STM32 - Einstieg mit Em::Blocks</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=STM32_-_Einstieg_mit_Em::Blocks&amp;diff=82098"/>
		<updated>2014-03-18T20:29:58Z</updated>

		<summary type="html">&lt;p&gt;Avrprogger: dsf&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In diesem Tutorial werde ich versuchen, möglichst einfach, die ersten Schritte zur Entwicklung von STM32 Anwenungen mit der Em::Blocks IDE zu erklären. Hier soll nicht so stark auf die einzelnen Peripherie-Module der Controller eingegangen werden, sondern mehr auf die IDE und die verschieden Libraries, wie die CMSIS Library, die DSP-Library, die Standard-Peripheral-Library, die USB-Library und vllt. über Ethernet. Ich denke ein Kapitel zu FreeRTOS wird es auch geben. Auserdem steht im Vordergrund Sachen wie z.B. booten aus dem SRAM, In-Application-Programming, FPU, Core-Coupled-RAM usw. Mal sehn wie weit ich komme ;)&lt;br /&gt;
&lt;br /&gt;
==Die Entwicklungsumgebung==&lt;br /&gt;
===Hardware===&lt;br /&gt;
Zum testen der Anwendungen, benutze ich das STM32F4-Discovery Board, welches einen Debugger, Peripherie und natürlich einen STM32 Controller (STM32F407VGT6) enthält. Deshalb sind alle Beispiele hier für den STM32F407VG Controller ausgelegt, können aber meisten 1:1 auf andere Controller portiert werden. Ich werde auch möglichsts keine STM32F4-Discovery Board spezifischen Libraries verwenden, damit der Portierungs-Vorgang möglichsts einfach bleibt.&lt;br /&gt;
&lt;br /&gt;
===Software===&lt;br /&gt;
In diesem Tutorial verwende ich [http://www.emblocks.org/ Em::Blocks] als IDE. Em::Blocks ist eine kostenlose, uneingeschränkte IDE, die alle STM32 Mikrcontroller unterstützt und sehr einfach zu bedienen ist.&lt;br /&gt;
nach dem Download kann die IDE per Dialog, sehr einfach, installiert werden. Als Compiler beinhaltet Em::Blocks den &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
Die IDE unterstützt zurzeit den ST-Link, den J-Link und es gibt eine Generic-Vorlage, durch welche andere Debugger konfiguriert werden können.&lt;br /&gt;
&lt;br /&gt;
Außerdem muss noch der passende Treiber für den Debugger installiert werden. Verwendet man ein Discovery-Board muss der [http://www.st.com/web/catalog/tools/FM146/CL1984/SC724/SS1677/PF251168 ST-Link/V2]-Treiber heruntergeladen und installiert werden. (Die Installation muss evtl. als Administrator ausgeführt werden, da sonst die Installation unvollständig wird.) Nach der Installation des Treibers kann man den Debugger über die entsprechende USB Schnittstelle an den PC anschließen und es sollte die Meldung von Windows kommen, dass der richtige Treiber gefunden wurde.&lt;br /&gt;
&lt;br /&gt;
===Libraries===&lt;br /&gt;
Zum programmieren benötigt man noch die [http://www.arm.com/products/processors/cortex-m/cortex-microcontroller-software-interface-standard.php CMSIS] und die Standard-Peripheral-Library (z.B. für die F4 Controller [http://www.st.com/stonline/stappl/productcatalog/app?page=partNumberSearchPage&amp;amp;levelid=SS1577&amp;amp;parentid=1743&amp;amp;resourcetype=SW Standard-Peripheral-Library-F4]), die man am besten in einen Ordner (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\STM32&#039;&#039;&#039;&#039;&#039;) entpackt&lt;br /&gt;
&lt;br /&gt;
==Basis-Wissen zur IDE==&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von Dateien zum Projekt===&lt;br /&gt;
Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf &amp;lt;ProjektName&amp;gt; -&amp;gt; Add files...&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Enfernen von Dateien aus dem Projekt===&lt;br /&gt;
Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf die Datei / mehrere Dateien auswählen -&amp;gt; Remove file from project&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
Die Dateien werden lediglich aus dem Projekt entfernt und nicht von der Festplatte gelöscht.&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von Include-Pfaden===&lt;br /&gt;
Sofern die Include-Datei(en) nicht im standard Include-Ordner &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; des Projektes liegen, muss man den Pfad zum Projekt hinzufügen, damit der Compiler die Include-Dateien später auch finden kann. Man geht wie folgt vor: Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; Search Directories -&amp;gt; Add&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von globalen Defines zum Build===&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; #defines&#039;&#039;&#039;&#039;&#039; können globale Defines hinzugefügt werden.&lt;br /&gt;
&lt;br /&gt;
===Compilieren===&lt;br /&gt;
Entweder über das &#039;&#039;&#039;&#039;&#039;Build&#039;&#039;&#039;&#039;&#039; Menü oder über &#039;&#039;&#039;&#039;&#039;F7&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Um eine genau Ausgabe des Compiler-Aufrufes mit allen Argumenten zu bekommen, geht man im &#039;&#039;&#039;&#039;&#039;Settings&#039;&#039;&#039;&#039;&#039; Menü auf &#039;&#039;&#039;&#039;&#039;Tools...&#039;&#039;&#039;&#039;&#039; und dann auf &#039;&#039;&#039;&#039;&#039;Toolchain executables&#039;&#039;&#039;&#039;&#039;. Ganz unten, unter &#039;&#039;&#039;&#039;&#039;Logging&#039;&#039;&#039;&#039;&#039; kann man dann &#039;&#039;&#039;&#039;&#039;Full command line&#039;&#039;&#039;&#039;&#039; auswählen.&lt;br /&gt;
&lt;br /&gt;
====Compiler Optionen====&lt;br /&gt;
=====Optimierung=====&lt;br /&gt;
Standardmäßig verwendet Em::Blocks keine Optimierung. Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; Categories: Optimization&#039;&#039;&#039;&#039;&#039; kann zwischen verschieden Optimierungen ausgewählt werden.&lt;br /&gt;
&lt;br /&gt;
=====Verschiedene C-Standards=====&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; Categories: Language standard&#039;&#039;&#039;&#039;&#039; kann man zwischen verschieden C-Standard auswählen, wie z.B, C99.&lt;br /&gt;
(Mit C99 können auch die Lauf-Variable in der for-Schleife deklariert werden: for(int i;..))&lt;br /&gt;
&lt;br /&gt;
===Debuggen===&lt;br /&gt;
*Als erstes den Debugger starten über das &#039;&#039;&#039;&#039;&#039;Debug&#039;&#039;&#039;&#039;&#039; Menü und &#039;&#039;&#039;&#039;&#039;Start/stop Debug Session&#039;&#039;&#039;&#039;&#039; oder über &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
*Danach läuft die Anwendung auf dem Controller und warten im &#039;&#039;&#039;&#039;&#039;Reset_Handler&#039;&#039;&#039;&#039;&#039; auf Einzelschritt- bzw. Run- Befehle (&#039;&#039;&#039;&#039;&#039;F5, F10, F11&#039;&#039;&#039;&#039;&#039; usw..(siehe &#039;&#039;&#039;&#039;&#039;Debug-Menü&#039;&#039;&#039;&#039;&#039; für alle Möglichkeiten))&lt;br /&gt;
&lt;br /&gt;
*Mit &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039; wird die Debug-Session auch wieder beendet&lt;br /&gt;
&lt;br /&gt;
*Unter &#039;&#039;&#039;&#039;&#039;Debug -&amp;gt; Interfaces -&amp;gt; Target settings&#039;&#039;&#039;&#039;&#039; können Eigenschaften, wie z.B &#039;&#039;&#039;&#039;&#039;Run to main()&#039;&#039;&#039;&#039;&#039; aktiviert werden.&lt;br /&gt;
&lt;br /&gt;
====Register View====&lt;br /&gt;
Damit man beim Debuggen sich bequem die Werte der Register (der Peripherie-Register) ansehen kann, bracht man eine, zum Controller passende &#039;&#039;&#039;&#039;&#039;System View Description&#039;&#039;&#039;&#039;&#039;-Datei (*.svd), die die verschiedenen Register beschreibt (Name, Adresse, usw..). In Em::Blocks gibt es dazu ein Tool, womit man solche Dateien herunterladen und verwenden kann.&lt;br /&gt;
&lt;br /&gt;
Um sich die nur die Core-Register anzusehen / zu bearbeiten braucht man keine SVD-Datei.&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;&#039;&#039;&#039;Debug&#039;&#039;&#039;&#039;&#039; -&amp;gt; &#039;&#039;&#039;&#039;&#039;Plugins&#039;&#039;&#039;&#039;&#039; -&amp;gt; &#039;&#039;&#039;&#039;&#039;SVD repository&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Controller-Hersteller und Cntroller-Reihe auswählen&lt;br /&gt;
*Speicherort auswählen (Standard ist das aktuelle Projekt-Verzeichniss)&lt;br /&gt;
*Wenn das Häkchen bei &#039;&#039;&#039;&#039;&#039;Set and launch target debug configuration&#039;&#039;&#039;&#039;&#039; gesetzt ist, öffnen sich die Debug-Einstellungen automatisch, und das neue SVD-File wird verwenden.&lt;br /&gt;
*Debug-Einstellungen mit &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; schließen&lt;br /&gt;
&lt;br /&gt;
===Projekt als Template abspeichern===&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;File -&amp;gt; Save project as template...&#039;&#039;&#039;&#039;&#039;. Das Template erscheint dann im Projekt-Dialog unter &#039;&#039;&#039;&#039;&#039;User templates&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Das erste Projekt erstellen==&lt;br /&gt;
Hier erkläre ich, wie man am Besten (aus meiner Sicht), ein neues Projekt von Grund auf erstellt, sodass man hinterher, den Controller-Kern über die CMSIS-Library und die Peripherie über die Register steuern kann.&lt;br /&gt;
&lt;br /&gt;
===1. Projekt mit der IDE erstellen===&lt;br /&gt;
Nach der Installation der oben beschriebenen Komponenten erstellt man am besten ein Verzeichnis (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\EmBlocks&#039;&#039;&#039;&#039;&#039;), indem später alle Projekte gespeichert werden. Für Libraries kann man auch noch ein Verzeichnis (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\STM32&#039;&#039;&#039;&#039;&#039;) erstellen, wo alle Libraries gespeichert werden, die man für die Projekt brauchen.&lt;br /&gt;
&lt;br /&gt;
Als nächstes starten man EmBlocks. Bei dem ersten Start öffnet sich ein Fenster, wo verschiedene Compiler angezeigt werden, die Em::Blocks findet. Dort wählt man den &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039; aus und klickt &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039;. Nun sollte sich das Hauptfenster von Em::Blocks öffnen. Über &#039;&#039;&#039;&#039;&#039;Create a new Project&#039;&#039;&#039;&#039;&#039; oder &#039;&#039;&#039;&#039;&#039;File -&amp;gt; New -&amp;gt; Project&#039;&#039;&#039;&#039;&#039; ruft man den Projekt-Dialog auf und kann ein neues Projekt erzeugen.&lt;br /&gt;
&lt;br /&gt;
Auf der Ersten Seite wählen man den &#039;&#039;&#039;&#039;&#039;STmicro-ARM&#039;&#039;&#039;&#039;&#039; Projekt-Typ aus.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_1.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auf der nächsten Seite wird man darauf hingewiesen, dass das der entsprechende Projekt-Typ-Dialog ausgeführt wird. Hier kann man ein Häkchen bei &#039;&#039;&#039;&#039;&#039;Skip this page next time&#039;&#039;&#039;&#039;&#039; setzen und auf &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; klicken.&lt;br /&gt;
&lt;br /&gt;
Im nächsten Schritt wählen man das zuvor erstellt Verzeichnis unter &#039;&#039;&#039;&#039;&#039;Folder to create Project in&#039;&#039;&#039;&#039;&#039; aus, indem später alle Projekt gespeichert werden. Außerdem geben wir dem Projekt einen Namen (z.B. &#039;&#039;&#039;&#039;&#039;FirstProject&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_2.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danach muss man einen Compiler auswählen und bestimmen, welche Projekt-Konfigurationen erszeugt werden sollen. Unter &#039;&#039;&#039;&#039;&#039;Compiler&#039;&#039;&#039;&#039;&#039; wählt man &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039; und man kann das Häkchen bei &#039;&#039;&#039;&#039;&#039;Create &amp;quot;Release&amp;quot; configuration&#039;&#039;&#039;&#039;&#039; entfernen, da diese unnötig ist, die Debug-Konfiguration sollte eig. immer ausreichen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_3.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auf den folgenden Seite wird der Controller ausgewählt. Verwendet man ein STM32F4-Discovery Board müssen folgende Dinge gewählt werden: &#039;&#039;&#039;&#039;&#039;Cortex_M4 (F3xx - F4xx) -&amp;gt; STM32F4xx (Cortex M4 with FPU) -&amp;gt; STM32F407VG&#039;&#039;&#039;&#039;&#039;. Leider sind die Auswahl Möglichkeiten nicht ganz richtig, da auch die F3 Controller einen Cortex M4 Kern und eine FPU haben (Ist aber nicht so wichtig, ist nur eine formale Sache). Außerdem entfernt man das Häkchen bei &#039;&#039;&#039;&#039;&#039;Standard Peripherals Library&#039;&#039;&#039;&#039;&#039; (Wie man die Standard-Peripheral-Library einbindet und verwendet erkläre ich später). Man kann auch das Häkchen bei &#039;&#039;&#039;&#039;&#039;Create hex file for Realease target&#039;&#039;&#039;&#039;&#039; entfernen.&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;Stack Size&#039;&#039;&#039;&#039;&#039; und &#039;&#039;&#039;&#039;&#039;Heap Size&#039;&#039;&#039;&#039;&#039; wird die Größe von Stack und Heap festgelegt. Für eine erste Anwendung kann man die Einstellungen so lassen (Stack-Size: 0x0100 =&amp;gt; 256 Byte Stack und Heap-Size: 0x0000 =&amp;gt; kein Heap). Mit &#039;&#039;&#039;&#039;&#039;Finish&#039;&#039;&#039;&#039;&#039; ist der Projekt Dialog abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_4.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danach sollten sich zwei neue Fenster öffnen, um die Debug-Eigenschaften fest zu legen.&lt;br /&gt;
Verwendet man ein Discovery Board/ST-Link müssen die Einstellungen wie auf dem Bild gewählt werden. Über den Button &#039;&#039;&#039;&#039;&#039;Settings&#039;&#039;&#039;&#039;&#039; öffnet sich das zweite Fenster, falls sich dieses nicht schon von alleine öffnen sollte. Nach den Schließen der Fenster über &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; ist der Projekt Dialog beendet und ein neues Projekt steht zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_5_1.png|Debug Eigenschaften 1. Fenster]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_5_2.png|Debug Eigenschaften 2. Fenster]]&lt;br /&gt;
&lt;br /&gt;
===2. CMSIS-Library und Startup-Code hinzufügen===&lt;br /&gt;
Wenn man sich, nachdem man ein neues Projekt in der IDE erstellt hat, die bereits vorhandenen Dateien im Projekt ansieht, stellt man fest, das bereits ein Ordner &#039;&#039;&#039;&#039;&#039;cmsis&#039;&#039;&#039;&#039;&#039; existiert, der einige wichtige Include-Dateien der CMSIS-Library enthält. Allerdings sind das wirklich nur die wichtigsten Include-Dateien der CMSIS-Library und dazu noch, die aus einer älternen Version. Ich ziehe es deshalb vor die &amp;quot;Mini-CMSIS-Libraray&amp;quot; und die &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c/.h&#039;&#039;&#039;&#039;&#039; Dateien des Projektes durch aktuellere Versionen zu ersetzen. So ist später auch die Integration  von anderen Libraries, wie z.B. der CMSIS-DSP-Libarary einfacher.  &lt;br /&gt;
&lt;br /&gt;
Zunächst gehen man in das Projekt-Verzeichnis und löscht:&lt;br /&gt;
*Den Ordner &#039;&#039;&#039;&#039;&#039;cmsis&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Alle Dateien im Include Verzeichnis &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; im &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner&lt;br /&gt;
&lt;br /&gt;
Außerdem entfernt man auch alle gelöschten Dateien in der IDE aus dem Projekt mit &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Rechts Klick -&amp;gt; Remove file from project&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Es sollte folgende Verzeichnis Struktur überbleiben:&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_6.png|Überbleibende Dateien]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Jetzt müssen die gelöschten Dateien durch die aktuelleren ersetzt werden.&lt;br /&gt;
&lt;br /&gt;
*Dazu kopieren man den gesamten Ordner &#039;&#039;&#039;&#039;&#039;CMSIS&#039;&#039;&#039;&#039;&#039; aus dem CMSIS Download in das Projekt Verzeichnis.&lt;br /&gt;
&lt;br /&gt;
*Aus dem Standard-Peripheral-Library Download kopiert man von &#039;&#039;&#039;&#039;&#039;Libraries\CMSIS\Device\ST\STM32F4xx\Include&#039;&#039;&#039;&#039;&#039; alle Dateien in den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projekt Verzeichnisses&lt;br /&gt;
&lt;br /&gt;
*Aus der Standard-Peripheral-Library kopieren man ebenfalls von &#039;&#039;&#039;&#039;&#039;Libraries\CMSIS\Device\ST\STM32F4xx\Source\Templates&#039;&#039;&#039;&#039;&#039; die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; in den &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner des Projekts&lt;br /&gt;
&lt;br /&gt;
Anschließend müssen die neuen Dateien in der IDE dem Projekt hinzugefügt werden. Dazu benutzt man &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Rechts Klick -&amp;gt; Add files&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
*Aus dem &#039;&#039;&#039;&#039;&#039;CMSIS&#039;&#039;&#039;&#039;&#039; Ordner im Projekt Verzeichnis werden aus den Unterorder &#039;&#039;&#039;&#039;&#039;Include&#039;&#039;&#039;&#039;&#039; folgende Dateien dem Projekt hinzugefügt:&lt;br /&gt;
**arm_common_tables.h&lt;br /&gt;
**arm_const_structs.h&lt;br /&gt;
**arm_math.h&lt;br /&gt;
**core_cm4.h&lt;br /&gt;
**core_cm4_simd.h&lt;br /&gt;
**core_cmFunc.h&lt;br /&gt;
**core_cmInstr.h&lt;br /&gt;
*Alle Dateien aus den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projektes&lt;br /&gt;
*Die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; aus dem &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner&lt;br /&gt;
&lt;br /&gt;
So sollte die Struktur dann aussehen:&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_7.png|Anwenungs-Grundgerüst]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Da einige Dateien der Libraries später bearbeitet werden müssen und Schreibgeschützt sind, weise ich hier schonmal darauf hin, das der Schreibschutz in der IDE über &#039;&#039;&#039;&#039;&#039;Rechts Klick auf die Datei -&amp;gt; Properties -&amp;gt; Häkchen bei &amp;quot;File is read only&amp;quot; entfernen&#039;&#039;&#039;&#039;&#039; entfert werden kann.&lt;br /&gt;
&lt;br /&gt;
Damit die IDE die Header-Dateien der CMSIS Library auch finden kann, weil diese ja nicht im standard Include Ordner &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; liegen, muss unter &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Build Options -&amp;gt; Search Directories&#039;&#039;&#039;&#039;&#039; der Pfad &#039;&#039;&#039;&#039;&#039;CMSIS\Include&#039;&#039;&#039;&#039;&#039; hinzugefügt werden.&lt;br /&gt;
&lt;br /&gt;
Compiliert man jetzt das Projekt mit &#039;&#039;&#039;&#039;&#039;F7&#039;&#039;&#039;&#039;&#039; gibt es ein paar Fehler Meldungen, weil keine Controller-Reihe ausgewählt wurde. Ebenfalls unter &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Build Options -&amp;gt; Compiler Settings -&amp;gt; #defines&#039;&#039;&#039;&#039;&#039; wird der Define &#039;&#039;&#039;&#039;&#039;STM32F40_41xxx&#039;&#039;&#039;&#039;&#039; hinzugefügt.&lt;br /&gt;
&lt;br /&gt;
Beim erneuten Compilieren sollten sich nun keine neuen Fehler ergeben.&lt;br /&gt;
&lt;br /&gt;
===3. Das erste Programm===&lt;br /&gt;
Nachdem ein grundsätzliches &amp;quot;Gerüst&amp;quot; fertig ist, kann man den ersten Code schreiben.&lt;br /&gt;
main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC-&amp;gt;AHB1ENR |= RCC_AHB1ENR_GPIODEN;    //Takt für GPIO aktivieren&lt;br /&gt;
    GPIOD-&amp;gt;MODER |= GPIO_MODER_MODER15_0;   //GPIOD Pin15 als Ausgang&lt;br /&gt;
    GPIOD-&amp;gt;BSRRL |= GPIO_BSRR_BS_15;        //GPIOD Pin15 auf High ziehen&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039; wird dann der Debugger gestartet. Hat der Debugger das Projekt erfolgreich übertragen kann die Ausführung mit &#039;&#039;&#039;&#039;&#039;F5&#039;&#039;&#039;&#039;&#039; begonnen werden.&lt;br /&gt;
&lt;br /&gt;
==Libraries einbinden/verwenden==&lt;br /&gt;
Um Libraries, wie hier im Tutorial, einzubinden, wird ein existierendes Projekt, wie ein im Kapitel [http://www.mikrocontroller.net/articles/STM32_-_Einstieg_mit_Em::Blocks#Das_erste_Projekt_erstellen Das Erste Projekt erstellen] beschrieben wird, vorausgesetzt.&lt;br /&gt;
&lt;br /&gt;
===Einbinden der Standard-Peripheral-Library===&lt;br /&gt;
Um nicht immer die einzelnen Register, wie im ersten &amp;quot;bare-metal&amp;quot; Beispiel, aus dem Reference-Manual zu suchen und zu beschreiben, gibt es von ST die Standard Peripheral Library, die diese Aufgaben übernimmt und mit der sich die &amp;quot;normale/grundlegende&amp;quot; (Alles außer USB und Ethernet) Peripherie recht einfach steuern lässt. Ich kopiere die Standard-Peripheral-Library immer per Hand in das Projekt. Darduch hat man auch gleich die aktuellste Version (in den älteren Version gibt es einige Bugs). &lt;br /&gt;
&lt;br /&gt;
*1. Den Ordner &#039;&#039;&#039;&#039;&#039;Libraries\STM32F4xx_StdPeriph_Driver&#039;&#039;&#039;&#039;&#039; aus dem Standard-Peripheral-Library Download in das Projekt-Verzeichnis kopieren&lt;br /&gt;
*2. Die Datei &#039;&#039;&#039;&#039;&#039;Project\STM32F4xx_StdPeriph_Templates\stm32f4xx_conf.h&#039;&#039;&#039;&#039;&#039; ebenfalls aus dem Standard-Peripheral-Library Download in den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projektes kopieren.&lt;br /&gt;
*3. In der IDE den Include-Path &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\inc&#039;&#039;&#039;&#039;&#039; hinzufügen&lt;br /&gt;
*4. Und das/den Define &#039;&#039;&#039;&#039;&#039;USE_STDPERIPH_DRIVER&#039;&#039;&#039;&#039;&#039; hinzufügen&lt;br /&gt;
*4. Source- und Include-Dateien zum Projekt hinzufügen&lt;br /&gt;
**Achtung: Es dürfen nur die Dateien hinzugefügt werden, für die der Controller auch die entsprechende Peripherie bereit stellt. Diese Dateien dürfen nicht beim STM32F4-Discovery/STM32F407VG hinzugefügt werden.&lt;br /&gt;
***stm32f4xx_dma2d.c/.h&lt;br /&gt;
***stm32f4xx_fmc.c/.h&lt;br /&gt;
***stm32f4xx_ltdc.c/.h&lt;br /&gt;
***stm32f4xx_sai.c/.h&lt;br /&gt;
&lt;br /&gt;
Daraus resultiert folgende Struktur:&lt;br /&gt;
&lt;br /&gt;
[[Datei:stdperiphlib_2.png|Header-Struktur]] [[Datei:stdperiphlib_1.png|Source-Struktur]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Anschließen kann die Standard-Peripheral-Library benutz werden.&lt;br /&gt;
main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);&lt;br /&gt;
&lt;br /&gt;
    GPIO_InitTypeDef GPIOD_InitStructure;&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Mode = GPIO_Mode_OUT;     //Als Ausgang&lt;br /&gt;
    GPIOD_InitStructure.GPIO_OType = GPIO_OType_PP;    //Push-Pull Betrieb&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Pin = GPIO_Pin_15;        //Pin 15 (STM32F4-Discovery: Blaue LED)&lt;br /&gt;
    GPIOD_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;  //Kein Pull-Up oder Pull-Down Widerstand aktiviert&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Speed = GPIO_Speed_25MHz; //25MHz Update-Rate&lt;br /&gt;
    GPIO_Init(GPIOD, &amp;amp;GPIOD_InitStructure);&lt;br /&gt;
&lt;br /&gt;
    GPIO_SetBits(GPIOD, GPIO_Pin_15);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hier ist noch ein &amp;quot;BasicFramework&amp;quot;, dass die komplette CMSIS- und Standard-Peripheral-Library enthält und kann Quasi als Basis für alle Projekte verwendet werden. Allerdings ist das Framework primär auf die STM32F405/7 und STM32F415/7 ausgelegt. Die neueren STM32F401, STM32F42X und STM32F43X  haben noch etwas andere Peripherie, dass Framework müsste dann entsprechend angepasst werden. Download: [[Datei:StdPeriphDriver_BasicFramework.zip]]&lt;br /&gt;
&lt;br /&gt;
===Einbinden der DSP-Library===&lt;br /&gt;
STM32F3 / STM32F4 Microcontroller haben neben der FPU noch einen Digital-Signal-Processor (DSP). Die DSP dient hauptsächlich dazu, viele Daten schnell zu verarbeiten (z.B. Video- oder Audiosignal). Der CMSIS-Download beinhaltet dazu neben der eigentlichen CMSIS-Library auch noch eine DSP-Library. Diese Library stellt sowohl einfache, mathematische Funktionen wie addieren, multiplizieren usw. als auch komplexe Funktionen, wie z.B  einen IIR-Filter, zur Verfügung. Die DSP-Library ist weiter aufgeteilt in kleinere Module, wie z.B. BasicMathFunctions, FilteringFunctions usw. (siehe &#039;&#039;&#039;&#039;&#039;CMSIS\DSP-Library\Source&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
*1. Source-Dateien des benötigten Moduls zum Projekt hinzufügen. (&#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Add files...&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
*2. &#039;&#039;&#039;&#039;&#039;arm_math.h&#039;&#039;&#039;&#039;&#039; in der &#039;&#039;&#039;&#039;&#039;main.c&#039;&#039;&#039;&#039;&#039; einbinden&lt;br /&gt;
*3. Damit die Warnung &amp;quot;Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)&amp;quot; verschwindet, muss der Define &#039;&#039;&#039;&#039;&#039;__FPU_PRESENT&#039;&#039;&#039;&#039;&#039; hinzugefügt werden. (Keine Ahnung, wieso es die Warnung gibt)&lt;br /&gt;
 &lt;br /&gt;
Jetzt kann die DSP-Library verwedet werden. Das Beispiel multipliziert zwei Buffer miteinander. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
#include &amp;quot;arm_math.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    float32_t x[1024];&lt;br /&gt;
    float32_t y[1024];&lt;br /&gt;
    float32_t z[1024];&lt;br /&gt;
&lt;br /&gt;
    for(uint16_t i = 0; i &amp;lt; 1024; i++)&lt;br /&gt;
    {&lt;br /&gt;
        x[i] = i;&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for(uint16_t i = 0; i &amp;lt; 1024; i++)&lt;br /&gt;
    {&lt;br /&gt;
        y[i] = PI;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    arm_mult_f32(x, y, z, 1024);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Startup-Code, Linker-Script, Takt, FPU usw.==&lt;br /&gt;
===Startup-Code===&lt;br /&gt;
Em::Blocks fügt standardmäßig einen Startup-Code mit in das Projekt ein. Die wichtigsten Dinge die darin erledigt werden sind folgende:&lt;br /&gt;
&lt;br /&gt;
*Stack und Heap wird angelgt&lt;br /&gt;
*Die Vector-Table wird angelegt&lt;br /&gt;
*Ein Default Reset-Handler wird implementiert, dieser erledigt folgende aufgaben:&lt;br /&gt;
**Kopieren der definierten Daten aus dem Flash in den SRAM&lt;br /&gt;
**&#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; wird aufgerufen, wenn &#039;&#039;&#039;&#039;&#039;__NO_SYSTEM_INIT&#039;&#039;&#039;&#039;&#039; nicht definiert ist&lt;br /&gt;
**Sprung in die &#039;&#039;&#039;&#039;&#039;main()&#039;&#039;&#039;&#039;&#039; Funktion&lt;br /&gt;
*Allen anderen Interrupt-Handler wird eine Default-Funktion &#039;&#039;&#039;&#039;&#039;def_irq_handler&#039;&#039;&#039;&#039;&#039; mit einer &#039;&#039;&#039;&#039;&#039;while(1)&#039;&#039;&#039;&#039;&#039;-Schleife zugewiesen, falls kein anderer Interrupt-Handler existiert.&lt;br /&gt;
&lt;br /&gt;
Normalerweise muss am Startup-Code nichts verändert werden.&lt;br /&gt;
&lt;br /&gt;
===Linker-Script===&lt;br /&gt;
Em::Blocks stellt zwei fertige Linker-Scripts bereit, eins für die Ausführung des Programmes aus dem Flash (&#039;&#039;&#039;&#039;&#039;*_flash.ld&#039;&#039;&#039;&#039;&#039;), das andere für die Ausführung aus dem SRAM (&#039;&#039;&#039;&#039;&#039;*_sram.ld&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Normalerweise muss auch hier nichts geändert werden, es sei den Daten sollen in bestimmten Adressbereichen abgelegt werden (z.B. im Core-Coupled RAM), was ich später noch zum Tutorial hinzufüge.&lt;br /&gt;
&lt;br /&gt;
===Der Takt===&lt;br /&gt;
Jeder Controller oder Prozessor braucht einen Takt, indem er die einzelnen Maschinen-Befehle abarbeiten kann.&lt;br /&gt;
Bei den STM32 Mikrocontrollern kann dieser Takt aus verschiedenen Quellen kommen:&lt;br /&gt;
&lt;br /&gt;
1. High Speed Internal Oszillator (HSI)&lt;br /&gt;
&lt;br /&gt;
2. High Speed External Oszillator (HSE)&lt;br /&gt;
&lt;br /&gt;
3. Low Speed Internal Oszillator (LSI)&lt;br /&gt;
&lt;br /&gt;
4. Low Speed External Oszillator (LSE)&lt;br /&gt;
&lt;br /&gt;
5. Phase-Locked Loop (PLL) (generiert den Takt aus den ersten vier Taktquellen durch Teiler und Faktoren)&lt;br /&gt;
&lt;br /&gt;
Nach einem Reset wird der Controller aus der HSI Taktquelle versorgt (16MHz beim STM32F407VG). Um die voll Performance des Controllers zu erreichen muss die PLL verwendet werden, welche den Takt durch geschickte Teiler und Faktoren vervielfältigt, sodass am Ende der Controller mit der maximalen Taktfrequenz läuft. Die notwendige Initialisierung der PLL findet in der Funktion &#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; statt. Die PLL erzeugt zunächst einen Basistakt:&lt;br /&gt;
&lt;br /&gt;
PLL_VCO = (F_HSE / PLL_M) * PLL_N&lt;br /&gt;
&lt;br /&gt;
Aus diesem Takt wird dann der Takt für den Controller-Kern abgeleitet:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = PLL_VCO / PLL_P&lt;br /&gt;
&lt;br /&gt;
Und der Takt für SDIO / USB / RNG (48MHz):&lt;br /&gt;
&lt;br /&gt;
48MHz = PLL_VCO / PLL_Q&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Durch weiter Teiler werden, die Takte für die einzelnen Busse erzeugt, da diese nicht alle beliebig schnell betrieben werden dürfen.&lt;br /&gt;
&lt;br /&gt;
Genaue Angaben findet man zu dem jeweiligen Clock-System des Controllers im Reference Manual.&lt;br /&gt;
&lt;br /&gt;
Ein Blick in den &amp;quot;Kommentar-Header&amp;quot; verrät, dass von einem externen (HSE) Oszillator von 25MHz ausgegangen wird, der die PLL versorgen soll.&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((25MHz / PLL_M(25)) * PLL_N(336)) / PLL_P(2) = 168MHz&lt;br /&gt;
&lt;br /&gt;
Allerdings stimmt diese Rechnung natürlich nur, wenn wirklich ein 25MHz Quarz am Controller angeschlossen ist. Auf dem STM32F4-Discovery Board befindet sich aber nur ein 8MHz Quarz. Demnach gilt:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((8MHz / PLL_M(25)) * PLL_N(336)) / PLL_P(2) = 53.76MHz&lt;br /&gt;
&lt;br /&gt;
Der Controller läuft also nur mit 53.76MHz, wenn wie ober beschrieben ein Projekt erstellt wird. Allerdings kann dieses Problem durch ändern von den betroffen Defines behoben werden:&lt;br /&gt;
 &lt;br /&gt;
*Dazu geht man in die &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; Datei und passt zur Vollständigkeit erstmal die zum Controller passende Tabelle im &amp;quot;Kommentar-Header&amp;quot; an (Z.57f):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      HSE Frequency(Hz)                      | 8000000&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      PLL_M                                  | 8&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Danach passt man den PPL_M Define (Z.254) an:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/************************* PLL Parameters *************************************/&lt;br /&gt;
/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */&lt;br /&gt;
#define PLL_M      8&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Außerdem muss man den HSE_VALUE Define in der &#039;&#039;&#039;&#039;&#039;inc/stm32f4xx.h&#039;&#039;&#039;&#039;&#039; angepasst werden (Z.122):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#if !defined  (HSE_VALUE)&lt;br /&gt;
  #define HSE_VALUE    ((uint32_t)8000000) /*!&amp;lt; Value of the External oscillator in Hz */&lt;br /&gt;
&lt;br /&gt;
#endif /* HSE_VALUE */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine neue Berechnung zeigt:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((8MHz / PLL_M(8)) * PLL_N(336)) / PLL_P(2) = 168MHz&lt;br /&gt;
&lt;br /&gt;
Jetzt läuft der Controller mit maximaler Geschwindigkeit.&lt;br /&gt;
&lt;br /&gt;
Die Theorie wird durch folgendes Programm verifiziert. Der geviertelte System-Takt SYSCLK wir am Pin PC9 ausgegeben. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);&lt;br /&gt;
&lt;br /&gt;
    GPIO_InitTypeDef GPIOC_InitStructure;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Mode = GPIO_Mode_AF;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_OType = GPIO_OType_PP;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Pin = GPIO_Pin_9;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;&lt;br /&gt;
    GPIO_Init(GPIOC, &amp;amp;GPIOC_InitStructure);&lt;br /&gt;
&lt;br /&gt;
    RCC_MCO2Config(RCC_MCO2Source_SYSCLK, RCC_MCO2Div_4);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Die FPU===&lt;br /&gt;
====Allgemeines====&lt;br /&gt;
STM32F3 und STM32F4 Controller haben eine FPU.&lt;br /&gt;
Damit die FPU richtig verwendet wird, müssen normalerweise zwei Bedingungen erfüllt sein:&lt;br /&gt;
&lt;br /&gt;
1. Der Controller muss die FPU Hardware-seitig aktivieren&lt;br /&gt;
&lt;br /&gt;
2. Damit die FPU auch was zu tuen bekommt, müssen vom Compiler FPU-Instructions erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
Die Em::Blocks IDE verwendet standardmäßig die FPU, wenn eine Vorhanden ist. Hier wird die FPU Hardware-seitig aktiviert (&#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; Z.341):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* FPU settings ------------------------------------------------------------*/&lt;br /&gt;
  #if (__FPU_PRESENT == 1) &amp;amp;&amp;amp; (__FPU_USED == 1)&lt;br /&gt;
    SCB-&amp;gt;CPACR |= ((3UL &amp;lt;&amp;lt; 10*2)|(3UL &amp;lt;&amp;lt; 11*2));  /* set CP10 and CP11 Full Access */&lt;br /&gt;
  #endif&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
__FPU_PRESENT wird in der &#039;&#039;&#039;&#039;&#039;stm32f4xx.h&#039;&#039;&#039;&#039;&#039; definiert.&lt;br /&gt;
__FPU_USED wird von der IDE übernommen (siehe Build-Log): &#039;&#039;&#039;&#039;&#039;-D__FPU_USED&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Außerdem wird der Compiler von der IDE standardmäßig mit dem Argument &#039;&#039;&#039;&#039;&#039;-mfloat-abi=hard&#039;&#039;&#039;&#039;&#039; aufgerufen, wodurch FPU-Instructions erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
====FPU abschalten====&lt;br /&gt;
Um die FPU ab zu schalten (Mir würde jetzt nur Strom sparen als Grund einfallen) geht man wie folgt vor:&lt;br /&gt;
&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; Device -&amp;gt; Policy&#039;&#039;&#039;&#039;&#039; wählt man &#039;&#039;&#039;&#039;&#039;Use target settings&#039;&#039;&#039;&#039;&#039; und über nimmt die Einstellungen, die vorher dort eingetragen waren, allerdings lässt man das Feld &#039;&#039;&#039;&#039;&#039;FP-hardware&#039;&#039;&#039;&#039;&#039; frei.&lt;br /&gt;
&lt;br /&gt;
[[Datei:fpu_1.png|FPU Abschalten Schritt 1]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;Compiler Settings -&amp;gt; Policy&#039;&#039;&#039;&#039;&#039; wählt man dann &#039;&#039;&#039;&#039;&#039;Use target options only&#039;&#039;&#039;&#039;&#039;. Dann kann man unter &#039;&#039;&#039;&#039;&#039;Categories&#039;&#039;&#039;&#039;&#039; die Option &#039;&#039;&#039;&#039;&#039;ARM FPU architecture&#039;&#039;&#039;&#039;&#039; auswählen. Dort stehen dann drei Möglichkeiten für die FPU zur Verfügung:&lt;br /&gt;
&lt;br /&gt;
1. Software-FPU-Library für Gleitkomma-Berechnung verwenden - Keine FPU-Instructions werden generiert (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=soft&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
2. Eine Mischung aus Software- und Hardware-FPU wird verwendet (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=softfp&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
3. Hardware-FPU wird für Gleitkomma-Berechnungen verwendet (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=hard&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
[[Datei:fpu_2.png|FPU Abschalten Schritt 2]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Um die FPU ab zu schalten wählt man natürlich die erste Möglichkeit.&lt;br /&gt;
Bei der 2. und 3. Möglichkeit fügt die IDE auch den Define &#039;&#039;&#039;&#039;&#039;__FPU_USED&#039;&#039;&#039;&#039;&#039; hinzu. Bei Der ersten Möglichkeit nicht. Der Code muss also nicht verändert / auskommentiert werden.&lt;br /&gt;
&lt;br /&gt;
Um die FPU wieder zu aktivieren müssen alle Schritte wieder rückgängig gemacht werden.&lt;br /&gt;
&lt;br /&gt;
Am besten ist es einfach mal alle Möglichkeiten im Einzelschritt durch zu probieren. Dann stellt man schnell fest, ob die FPU aktiviert wir oder nicht. Ein Blick in den erweiterten &#039;&#039;&#039;&#039;&#039;Build-Log&#039;&#039;&#039;&#039;&#039; gibt auch schnell Aufschluss darüber, wie der Compiler aufgerufen wird (siehe Kapitel [http://www.mikrocontroller.net/articles/STM32_-_Einstieg_mit_Em::Blocks#Compilieren Compilieren]).&lt;br /&gt;
&lt;br /&gt;
====Test Programm für die FPU====&lt;br /&gt;
Hier ein kleines Testprogramm, dass misst wie viele Taktzyklen für eine Gleitkomma-Multiplikation gebraucht werden. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define CORE_SysTickEn()    (*((u32*)0xE0001000)) = 0x40000001&lt;br /&gt;
#define CORE_SysTickDis()   (*((u32*)0xE0001000)) = 0x40000000&lt;br /&gt;
#define CORE_GetSysTick()   (*((u32*)0xE0001004))&lt;br /&gt;
&lt;br /&gt;
uint32_t t1, t2, dt;&lt;br /&gt;
float x, y, z;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    x = 53.64f;&lt;br /&gt;
    y = 0.27f;&lt;br /&gt;
&lt;br /&gt;
    CORE_SysTickEn();&lt;br /&gt;
    t1 = CORE_GetSysTick();&lt;br /&gt;
&lt;br /&gt;
    z = x * y;&lt;br /&gt;
&lt;br /&gt;
    t2 = CORE_GetSysTick();&lt;br /&gt;
    CORE_SysTickDis();&lt;br /&gt;
&lt;br /&gt;
    dt = (t2 - t1) - 9; //9 Takt-Zyklen werden für die Messung gebraucht &lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Core-Coupled-RAM verwenden===&lt;br /&gt;
Auf den normale SRAM kann durch den Core und die verschiedenen DMA-Controller zugegriffen werden. Jedoch können Core und DMA nicht gleichzeitig auf den SRAM zugreifen. Deswegen gibt es einen zweiten kleinen RAM, den Core-Coupled-RAM (CCRAM), auf den nur vom Core zugegriffen werden kann und nicht von einem DMA-Controller. Der CCRAM ist über einen anderen Bus an dem Cortex angeschlossen. Daduch wird ermöglicht, dass der Core sinnvoll weiterarbeiten kann, wenn ein DMA-Controller Daten aus den &amp;quot;Haupt&amp;quot;-RAM ließt/schreibt, indem der Core Daten aus dem CCRAM verarbeitet. Um Daten in den CCRAM zu legen, geht man wie folgt vor:&lt;br /&gt;
&lt;br /&gt;
1. Eine neue Section im Linkerscript anlegen:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
Sections:&lt;br /&gt;
{&lt;br /&gt;
  ...&lt;br /&gt;
&lt;br /&gt;
  .ccram :&lt;br /&gt;
  {&lt;br /&gt;
    *(.ccram)&lt;br /&gt;
  } &amp;gt; CCRAM&lt;br /&gt;
&lt;br /&gt;
  ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Um die neue Section zu verwenden benutzt man diesen Define:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#define CCRAM __attribute__((section(&amp;quot;.ccram&amp;quot;)))&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
int CCRAM dataInCCRAM;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Beim Debuggen stellt man fest das die Variable an der Adresse 0x10000000 liegt, der ersten Adresse das CCRAM&#039;s.&lt;br /&gt;
&lt;br /&gt;
==Booten aus dem SRAM==&lt;br /&gt;
STM32 Controller haben die Möglichkeit Code aus dem Flash als auch aus dem SRAM auszuführen. Um eine Anwenung per Debugger in des SRAM zu laden sind nur wenige Schritte erforderlich:&lt;br /&gt;
&lt;br /&gt;
*Um das Linkerscript für den SRAM zu verwenden geht man zu: &#039;&#039;&#039;&#039;&#039;Build options... -&amp;gt; Device&#039;&#039;&#039;&#039;&#039; dort wählt man unter &#039;&#039;&#039;&#039;&#039;Policy&#039;&#039;&#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;Use target settings&#039;&#039;&#039;&#039;&#039; aus und übernimmt die vorherigen Einstellungen, nur unter &#039;&#039;&#039;&#039;&#039;Linker script*&#039;&#039;&#039;&#039;&#039; gibt man &#039;&#039;&#039;&#039;&#039;.\stm32f407vg_sram.ld&#039;&#039;&#039;&#039;&#039; an&lt;br /&gt;
&lt;br /&gt;
*Dann muss man noch unter &#039;&#039;&#039;&#039;&#039;Debug -&amp;gt; Interfaces -&amp;gt; Settings&#039;&#039;&#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;Vector table start&#039;&#039;&#039;&#039;&#039; auf 0x20000000 ändern und &#039;&#039;&#039;&#039;&#039;Execute from RAM&#039;&#039;&#039;&#039;&#039; auswählen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:bootsram_1.png Booten aus dem SRAM]] [[Datei:bootsram_2.png Booten aus dem SRAM]]&lt;br /&gt;
&lt;br /&gt;
Anschließend kann man die Anwendung ganz normal debuggen. Nach einem Reset muss die Anwenung erneut mit dem Debugger gestartet werden.&lt;br /&gt;
&lt;br /&gt;
=Fortsetzung folgt..=&lt;br /&gt;
Kritik, Wünsche usw. sind gerne erwünscht, am besten hier in den Thread posten: [http://www.mikrocontroller.net/topic/323750 Neues STM32 Tutorial]&lt;br /&gt;
&lt;br /&gt;
[[Category:ARM]]&lt;br /&gt;
[[Category:STM32]]&lt;/div&gt;</summary>
		<author><name>Avrprogger</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=STM32_-_Einstieg_mit_Em::Blocks&amp;diff=82097</id>
		<title>STM32 - Einstieg mit Em::Blocks</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=STM32_-_Einstieg_mit_Em::Blocks&amp;diff=82097"/>
		<updated>2014-03-18T20:28:20Z</updated>

		<summary type="html">&lt;p&gt;Avrprogger: svd&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In diesem Tutorial werde ich versuchen, möglichst einfach, die ersten Schritte zur Entwicklung von STM32 Anwenungen mit der Em::Blocks IDE zu erklären. Hier soll nicht so stark auf die einzelnen Peripherie-Module der Controller eingegangen werden, sondern mehr auf die IDE und die verschieden Libraries, wie die CMSIS Library, die DSP-Library, die Standard-Peripheral-Library, die USB-Library und vllt. über Ethernet. Ich denke ein Kapitel zu FreeRTOS wird es auch geben. Auserdem steht im Vordergrund Sachen wie z.B. booten aus dem SRAM, In-Application-Programming, FPU, Core-Coupled-RAM usw. Mal sehn wie weit ich komme ;)&lt;br /&gt;
&lt;br /&gt;
==Die Entwicklungsumgebung==&lt;br /&gt;
===Hardware===&lt;br /&gt;
Zum testen der Anwendungen, benutze ich das STM32F4-Discovery Board, welches einen Debugger, Peripherie und natürlich einen STM32 Controller (STM32F407VGT6) enthält. Deshalb sind alle Beispiele hier für den STM32F407VG Controller ausgelegt, können aber meisten 1:1 auf andere Controller portiert werden. Ich werde auch möglichsts keine STM32F4-Discovery Board spezifischen Libraries verwenden, damit der Portierungs-Vorgang möglichsts einfach bleibt.&lt;br /&gt;
&lt;br /&gt;
===Software===&lt;br /&gt;
In diesem Tutorial verwende ich [http://www.emblocks.org/ Em::Blocks] als IDE. Em::Blocks ist eine kostenlose, uneingeschränkte IDE, die alle STM32 Mikrcontroller unterstützt und sehr einfach zu bedienen ist.&lt;br /&gt;
nach dem Download kann die IDE per Dialog, sehr einfach, installiert werden. Als Compiler beinhaltet Em::Blocks den &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
Die IDE unterstützt zurzeit den ST-Link, den J-Link und es gibt eine Generic-Vorlage, durch welche andere Debugger konfiguriert werden können.&lt;br /&gt;
&lt;br /&gt;
Außerdem muss noch der passende Treiber für den Debugger installiert werden. Verwendet man ein Discovery-Board muss der [http://www.st.com/web/catalog/tools/FM146/CL1984/SC724/SS1677/PF251168 ST-Link/V2]-Treiber heruntergeladen und installiert werden. (Die Installation muss evtl. als Administrator ausgeführt werden, da sonst die Installation unvollständig wird.) Nach der Installation des Treibers kann man den Debugger über die entsprechende USB Schnittstelle an den PC anschließen und es sollte die Meldung von Windows kommen, dass der richtige Treiber gefunden wurde.&lt;br /&gt;
&lt;br /&gt;
===Libraries===&lt;br /&gt;
Zum programmieren benötigt man noch die [http://www.arm.com/products/processors/cortex-m/cortex-microcontroller-software-interface-standard.php CMSIS] und die Standard-Peripheral-Library (z.B. für die F4 Controller [http://www.st.com/stonline/stappl/productcatalog/app?page=partNumberSearchPage&amp;amp;levelid=SS1577&amp;amp;parentid=1743&amp;amp;resourcetype=SW Standard-Peripheral-Library-F4]), die man am besten in einen Ordner (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\STM32&#039;&#039;&#039;&#039;&#039;) entpackt&lt;br /&gt;
&lt;br /&gt;
==Basis-Wissen zur IDE==&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von Dateien zum Projekt===&lt;br /&gt;
Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf &amp;lt;ProjektName&amp;gt; -&amp;gt; Add files...&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Enfernen von Dateien aus dem Projekt===&lt;br /&gt;
Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf die Datei / mehrere Dateien auswählen -&amp;gt; Remove file from project&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
Die Dateien werden lediglich aus dem Projekt entfernt und nicht von der Festplatte gelöscht.&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von Include-Pfaden===&lt;br /&gt;
Sofern die Include-Datei(en) nicht im standard Include-Ordner &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; des Projektes liegen, muss man den Pfad zum Projekt hinzufügen, damit der Compiler die Include-Dateien später auch finden kann. Man geht wie folgt vor: Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; Search Directories -&amp;gt; Add&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von globalen Defines zum Build===&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; #defines&#039;&#039;&#039;&#039;&#039; können globale Defines hinzugefügt werden.&lt;br /&gt;
&lt;br /&gt;
===Compilieren===&lt;br /&gt;
Entweder über das &#039;&#039;&#039;&#039;&#039;Build&#039;&#039;&#039;&#039;&#039; Menü oder über &#039;&#039;&#039;&#039;&#039;F7&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Um eine genau Ausgabe des Compiler-Aufrufes mit allen Argumenten zu bekommen, geht man im &#039;&#039;&#039;&#039;&#039;Settings&#039;&#039;&#039;&#039;&#039; Menü auf &#039;&#039;&#039;&#039;&#039;Tools...&#039;&#039;&#039;&#039;&#039; und dann auf &#039;&#039;&#039;&#039;&#039;Toolchain executables&#039;&#039;&#039;&#039;&#039;. Ganz unten, unter &#039;&#039;&#039;&#039;&#039;Logging&#039;&#039;&#039;&#039;&#039; kann man dann &#039;&#039;&#039;&#039;&#039;Full command line&#039;&#039;&#039;&#039;&#039; auswählen.&lt;br /&gt;
&lt;br /&gt;
====Compiler Optionen====&lt;br /&gt;
=====Optimierung=====&lt;br /&gt;
Standardmäßig verwendet Em::Blocks keine Optimierung. Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; Categories: Optimization&#039;&#039;&#039;&#039;&#039; kann zwischen verschieden Optimierungen ausgewählt werden.&lt;br /&gt;
&lt;br /&gt;
=====Verschiedene C-Standards=====&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; Categories: Language standard&#039;&#039;&#039;&#039;&#039; kann man zwischen verschieden C-Standard auswählen, wie z.B, C99.&lt;br /&gt;
(Mit C99 können auch die Lauf-Variable in der for-Schleife deklariert werden: for(int i;..))&lt;br /&gt;
&lt;br /&gt;
===Debuggen===&lt;br /&gt;
*Als erstes den Debugger starten über das &#039;&#039;&#039;&#039;&#039;Debug&#039;&#039;&#039;&#039;&#039; Menü und &#039;&#039;&#039;&#039;&#039;Start/stop Debug Session&#039;&#039;&#039;&#039;&#039; oder über &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
*Danach läuft die Anwendung auf dem Controller und warten im &#039;&#039;&#039;&#039;&#039;Reset_Handler&#039;&#039;&#039;&#039;&#039; auf Einzelschritt- bzw. Run- Befehle (&#039;&#039;&#039;&#039;&#039;F5, F10, F11&#039;&#039;&#039;&#039;&#039; usw..(siehe &#039;&#039;&#039;&#039;&#039;Debug-Menü&#039;&#039;&#039;&#039;&#039; für alle Möglichkeiten))&lt;br /&gt;
&lt;br /&gt;
*Mit &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039; wird die Debug-Session auch wieder beendet&lt;br /&gt;
&lt;br /&gt;
*Unter &#039;&#039;&#039;&#039;&#039;Debug -&amp;gt; Interfaces -&amp;gt; Target settings&#039;&#039;&#039;&#039;&#039; können Eigenschaften, wie z.B &#039;&#039;&#039;&#039;&#039;Run to main()&#039;&#039;&#039;&#039;&#039; aktiviert werden.&lt;br /&gt;
&lt;br /&gt;
====Register View====&lt;br /&gt;
Damit man beim Debuggen sich bequem die Werte der Register (der Peripherie-Register) ansehen kann, bracht man eine, zum Controller passende &#039;&#039;&#039;&#039;&#039;System View Description&#039;&#039;&#039;&#039;&#039;-Datei (*.svd), die die verschiedenen Register beschreibt (Name, Adresse, usw..). In Em::Blocks gibt es dazu ein Tool, womit man solche Dateien herunterladen und verwenden kann.&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;&#039;&#039;&#039;Debug&#039;&#039;&#039;&#039;&#039; -&amp;gt; &#039;&#039;&#039;&#039;&#039;Plugins&#039;&#039;&#039;&#039;&#039; -&amp;gt; &#039;&#039;&#039;&#039;&#039;SVD repository&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Controller-Hersteller und Cntroller-Reihe auswählen&lt;br /&gt;
*Speicherort auswählen (Standard ist das aktuelle Projekt-Verzeichniss)&lt;br /&gt;
*Wenn das Häkchen bei &#039;&#039;&#039;&#039;&#039;Set and launch target debug configuration&#039;&#039;&#039;&#039;&#039; gesetzt ist, öffnen sich die Debug-Einstellungen automatisch, und das neue *.svd-File wird verwenden.&lt;br /&gt;
*Debug-Einstellungen mit &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; schließen&lt;br /&gt;
&lt;br /&gt;
===Projekt als Template abspeichern===&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;File -&amp;gt; Save project as template...&#039;&#039;&#039;&#039;&#039;. Das Template erscheint dann im Projekt-Dialog unter &#039;&#039;&#039;&#039;&#039;User templates&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Das erste Projekt erstellen==&lt;br /&gt;
Hier erkläre ich, wie man am Besten (aus meiner Sicht), ein neues Projekt von Grund auf erstellt, sodass man hinterher, den Controller-Kern über die CMSIS-Library und die Peripherie über die Register steuern kann.&lt;br /&gt;
&lt;br /&gt;
===1. Projekt mit der IDE erstellen===&lt;br /&gt;
Nach der Installation der oben beschriebenen Komponenten erstellt man am besten ein Verzeichnis (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\EmBlocks&#039;&#039;&#039;&#039;&#039;), indem später alle Projekte gespeichert werden. Für Libraries kann man auch noch ein Verzeichnis (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\STM32&#039;&#039;&#039;&#039;&#039;) erstellen, wo alle Libraries gespeichert werden, die man für die Projekt brauchen.&lt;br /&gt;
&lt;br /&gt;
Als nächstes starten man EmBlocks. Bei dem ersten Start öffnet sich ein Fenster, wo verschiedene Compiler angezeigt werden, die Em::Blocks findet. Dort wählt man den &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039; aus und klickt &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039;. Nun sollte sich das Hauptfenster von Em::Blocks öffnen. Über &#039;&#039;&#039;&#039;&#039;Create a new Project&#039;&#039;&#039;&#039;&#039; oder &#039;&#039;&#039;&#039;&#039;File -&amp;gt; New -&amp;gt; Project&#039;&#039;&#039;&#039;&#039; ruft man den Projekt-Dialog auf und kann ein neues Projekt erzeugen.&lt;br /&gt;
&lt;br /&gt;
Auf der Ersten Seite wählen man den &#039;&#039;&#039;&#039;&#039;STmicro-ARM&#039;&#039;&#039;&#039;&#039; Projekt-Typ aus.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_1.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auf der nächsten Seite wird man darauf hingewiesen, dass das der entsprechende Projekt-Typ-Dialog ausgeführt wird. Hier kann man ein Häkchen bei &#039;&#039;&#039;&#039;&#039;Skip this page next time&#039;&#039;&#039;&#039;&#039; setzen und auf &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; klicken.&lt;br /&gt;
&lt;br /&gt;
Im nächsten Schritt wählen man das zuvor erstellt Verzeichnis unter &#039;&#039;&#039;&#039;&#039;Folder to create Project in&#039;&#039;&#039;&#039;&#039; aus, indem später alle Projekt gespeichert werden. Außerdem geben wir dem Projekt einen Namen (z.B. &#039;&#039;&#039;&#039;&#039;FirstProject&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_2.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danach muss man einen Compiler auswählen und bestimmen, welche Projekt-Konfigurationen erszeugt werden sollen. Unter &#039;&#039;&#039;&#039;&#039;Compiler&#039;&#039;&#039;&#039;&#039; wählt man &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039; und man kann das Häkchen bei &#039;&#039;&#039;&#039;&#039;Create &amp;quot;Release&amp;quot; configuration&#039;&#039;&#039;&#039;&#039; entfernen, da diese unnötig ist, die Debug-Konfiguration sollte eig. immer ausreichen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_3.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auf den folgenden Seite wird der Controller ausgewählt. Verwendet man ein STM32F4-Discovery Board müssen folgende Dinge gewählt werden: &#039;&#039;&#039;&#039;&#039;Cortex_M4 (F3xx - F4xx) -&amp;gt; STM32F4xx (Cortex M4 with FPU) -&amp;gt; STM32F407VG&#039;&#039;&#039;&#039;&#039;. Leider sind die Auswahl Möglichkeiten nicht ganz richtig, da auch die F3 Controller einen Cortex M4 Kern und eine FPU haben (Ist aber nicht so wichtig, ist nur eine formale Sache). Außerdem entfernt man das Häkchen bei &#039;&#039;&#039;&#039;&#039;Standard Peripherals Library&#039;&#039;&#039;&#039;&#039; (Wie man die Standard-Peripheral-Library einbindet und verwendet erkläre ich später). Man kann auch das Häkchen bei &#039;&#039;&#039;&#039;&#039;Create hex file for Realease target&#039;&#039;&#039;&#039;&#039; entfernen.&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;Stack Size&#039;&#039;&#039;&#039;&#039; und &#039;&#039;&#039;&#039;&#039;Heap Size&#039;&#039;&#039;&#039;&#039; wird die Größe von Stack und Heap festgelegt. Für eine erste Anwendung kann man die Einstellungen so lassen (Stack-Size: 0x0100 =&amp;gt; 256 Byte Stack und Heap-Size: 0x0000 =&amp;gt; kein Heap). Mit &#039;&#039;&#039;&#039;&#039;Finish&#039;&#039;&#039;&#039;&#039; ist der Projekt Dialog abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_4.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danach sollten sich zwei neue Fenster öffnen, um die Debug-Eigenschaften fest zu legen.&lt;br /&gt;
Verwendet man ein Discovery Board/ST-Link müssen die Einstellungen wie auf dem Bild gewählt werden. Über den Button &#039;&#039;&#039;&#039;&#039;Settings&#039;&#039;&#039;&#039;&#039; öffnet sich das zweite Fenster, falls sich dieses nicht schon von alleine öffnen sollte. Nach den Schließen der Fenster über &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; ist der Projekt Dialog beendet und ein neues Projekt steht zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_5_1.png|Debug Eigenschaften 1. Fenster]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_5_2.png|Debug Eigenschaften 2. Fenster]]&lt;br /&gt;
&lt;br /&gt;
===2. CMSIS-Library und Startup-Code hinzufügen===&lt;br /&gt;
Wenn man sich, nachdem man ein neues Projekt in der IDE erstellt hat, die bereits vorhandenen Dateien im Projekt ansieht, stellt man fest, das bereits ein Ordner &#039;&#039;&#039;&#039;&#039;cmsis&#039;&#039;&#039;&#039;&#039; existiert, der einige wichtige Include-Dateien der CMSIS-Library enthält. Allerdings sind das wirklich nur die wichtigsten Include-Dateien der CMSIS-Library und dazu noch, die aus einer älternen Version. Ich ziehe es deshalb vor die &amp;quot;Mini-CMSIS-Libraray&amp;quot; und die &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c/.h&#039;&#039;&#039;&#039;&#039; Dateien des Projektes durch aktuellere Versionen zu ersetzen. So ist später auch die Integration  von anderen Libraries, wie z.B. der CMSIS-DSP-Libarary einfacher.  &lt;br /&gt;
&lt;br /&gt;
Zunächst gehen man in das Projekt-Verzeichnis und löscht:&lt;br /&gt;
*Den Ordner &#039;&#039;&#039;&#039;&#039;cmsis&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Alle Dateien im Include Verzeichnis &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; im &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner&lt;br /&gt;
&lt;br /&gt;
Außerdem entfernt man auch alle gelöschten Dateien in der IDE aus dem Projekt mit &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Rechts Klick -&amp;gt; Remove file from project&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Es sollte folgende Verzeichnis Struktur überbleiben:&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_6.png|Überbleibende Dateien]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Jetzt müssen die gelöschten Dateien durch die aktuelleren ersetzt werden.&lt;br /&gt;
&lt;br /&gt;
*Dazu kopieren man den gesamten Ordner &#039;&#039;&#039;&#039;&#039;CMSIS&#039;&#039;&#039;&#039;&#039; aus dem CMSIS Download in das Projekt Verzeichnis.&lt;br /&gt;
&lt;br /&gt;
*Aus dem Standard-Peripheral-Library Download kopiert man von &#039;&#039;&#039;&#039;&#039;Libraries\CMSIS\Device\ST\STM32F4xx\Include&#039;&#039;&#039;&#039;&#039; alle Dateien in den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projekt Verzeichnisses&lt;br /&gt;
&lt;br /&gt;
*Aus der Standard-Peripheral-Library kopieren man ebenfalls von &#039;&#039;&#039;&#039;&#039;Libraries\CMSIS\Device\ST\STM32F4xx\Source\Templates&#039;&#039;&#039;&#039;&#039; die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; in den &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner des Projekts&lt;br /&gt;
&lt;br /&gt;
Anschließend müssen die neuen Dateien in der IDE dem Projekt hinzugefügt werden. Dazu benutzt man &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Rechts Klick -&amp;gt; Add files&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
*Aus dem &#039;&#039;&#039;&#039;&#039;CMSIS&#039;&#039;&#039;&#039;&#039; Ordner im Projekt Verzeichnis werden aus den Unterorder &#039;&#039;&#039;&#039;&#039;Include&#039;&#039;&#039;&#039;&#039; folgende Dateien dem Projekt hinzugefügt:&lt;br /&gt;
**arm_common_tables.h&lt;br /&gt;
**arm_const_structs.h&lt;br /&gt;
**arm_math.h&lt;br /&gt;
**core_cm4.h&lt;br /&gt;
**core_cm4_simd.h&lt;br /&gt;
**core_cmFunc.h&lt;br /&gt;
**core_cmInstr.h&lt;br /&gt;
*Alle Dateien aus den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projektes&lt;br /&gt;
*Die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; aus dem &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner&lt;br /&gt;
&lt;br /&gt;
So sollte die Struktur dann aussehen:&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_7.png|Anwenungs-Grundgerüst]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Da einige Dateien der Libraries später bearbeitet werden müssen und Schreibgeschützt sind, weise ich hier schonmal darauf hin, das der Schreibschutz in der IDE über &#039;&#039;&#039;&#039;&#039;Rechts Klick auf die Datei -&amp;gt; Properties -&amp;gt; Häkchen bei &amp;quot;File is read only&amp;quot; entfernen&#039;&#039;&#039;&#039;&#039; entfert werden kann.&lt;br /&gt;
&lt;br /&gt;
Damit die IDE die Header-Dateien der CMSIS Library auch finden kann, weil diese ja nicht im standard Include Ordner &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; liegen, muss unter &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Build Options -&amp;gt; Search Directories&#039;&#039;&#039;&#039;&#039; der Pfad &#039;&#039;&#039;&#039;&#039;CMSIS\Include&#039;&#039;&#039;&#039;&#039; hinzugefügt werden.&lt;br /&gt;
&lt;br /&gt;
Compiliert man jetzt das Projekt mit &#039;&#039;&#039;&#039;&#039;F7&#039;&#039;&#039;&#039;&#039; gibt es ein paar Fehler Meldungen, weil keine Controller-Reihe ausgewählt wurde. Ebenfalls unter &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Build Options -&amp;gt; Compiler Settings -&amp;gt; #defines&#039;&#039;&#039;&#039;&#039; wird der Define &#039;&#039;&#039;&#039;&#039;STM32F40_41xxx&#039;&#039;&#039;&#039;&#039; hinzugefügt.&lt;br /&gt;
&lt;br /&gt;
Beim erneuten Compilieren sollten sich nun keine neuen Fehler ergeben.&lt;br /&gt;
&lt;br /&gt;
===3. Das erste Programm===&lt;br /&gt;
Nachdem ein grundsätzliches &amp;quot;Gerüst&amp;quot; fertig ist, kann man den ersten Code schreiben.&lt;br /&gt;
main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC-&amp;gt;AHB1ENR |= RCC_AHB1ENR_GPIODEN;    //Takt für GPIO aktivieren&lt;br /&gt;
    GPIOD-&amp;gt;MODER |= GPIO_MODER_MODER15_0;   //GPIOD Pin15 als Ausgang&lt;br /&gt;
    GPIOD-&amp;gt;BSRRL |= GPIO_BSRR_BS_15;        //GPIOD Pin15 auf High ziehen&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039; wird dann der Debugger gestartet. Hat der Debugger das Projekt erfolgreich übertragen kann die Ausführung mit &#039;&#039;&#039;&#039;&#039;F5&#039;&#039;&#039;&#039;&#039; begonnen werden.&lt;br /&gt;
&lt;br /&gt;
==Libraries einbinden/verwenden==&lt;br /&gt;
Um Libraries, wie hier im Tutorial, einzubinden, wird ein existierendes Projekt, wie ein im Kapitel [http://www.mikrocontroller.net/articles/STM32_-_Einstieg_mit_Em::Blocks#Das_erste_Projekt_erstellen Das Erste Projekt erstellen] beschrieben wird, vorausgesetzt.&lt;br /&gt;
&lt;br /&gt;
===Einbinden der Standard-Peripheral-Library===&lt;br /&gt;
Um nicht immer die einzelnen Register, wie im ersten &amp;quot;bare-metal&amp;quot; Beispiel, aus dem Reference-Manual zu suchen und zu beschreiben, gibt es von ST die Standard Peripheral Library, die diese Aufgaben übernimmt und mit der sich die &amp;quot;normale/grundlegende&amp;quot; (Alles außer USB und Ethernet) Peripherie recht einfach steuern lässt. Ich kopiere die Standard-Peripheral-Library immer per Hand in das Projekt. Darduch hat man auch gleich die aktuellste Version (in den älteren Version gibt es einige Bugs). &lt;br /&gt;
&lt;br /&gt;
*1. Den Ordner &#039;&#039;&#039;&#039;&#039;Libraries\STM32F4xx_StdPeriph_Driver&#039;&#039;&#039;&#039;&#039; aus dem Standard-Peripheral-Library Download in das Projekt-Verzeichnis kopieren&lt;br /&gt;
*2. Die Datei &#039;&#039;&#039;&#039;&#039;Project\STM32F4xx_StdPeriph_Templates\stm32f4xx_conf.h&#039;&#039;&#039;&#039;&#039; ebenfalls aus dem Standard-Peripheral-Library Download in den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projektes kopieren.&lt;br /&gt;
*3. In der IDE den Include-Path &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\inc&#039;&#039;&#039;&#039;&#039; hinzufügen&lt;br /&gt;
*4. Und das/den Define &#039;&#039;&#039;&#039;&#039;USE_STDPERIPH_DRIVER&#039;&#039;&#039;&#039;&#039; hinzufügen&lt;br /&gt;
*4. Source- und Include-Dateien zum Projekt hinzufügen&lt;br /&gt;
**Achtung: Es dürfen nur die Dateien hinzugefügt werden, für die der Controller auch die entsprechende Peripherie bereit stellt. Diese Dateien dürfen nicht beim STM32F4-Discovery/STM32F407VG hinzugefügt werden.&lt;br /&gt;
***stm32f4xx_dma2d.c/.h&lt;br /&gt;
***stm32f4xx_fmc.c/.h&lt;br /&gt;
***stm32f4xx_ltdc.c/.h&lt;br /&gt;
***stm32f4xx_sai.c/.h&lt;br /&gt;
&lt;br /&gt;
Daraus resultiert folgende Struktur:&lt;br /&gt;
&lt;br /&gt;
[[Datei:stdperiphlib_2.png|Header-Struktur]] [[Datei:stdperiphlib_1.png|Source-Struktur]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Anschließen kann die Standard-Peripheral-Library benutz werden.&lt;br /&gt;
main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);&lt;br /&gt;
&lt;br /&gt;
    GPIO_InitTypeDef GPIOD_InitStructure;&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Mode = GPIO_Mode_OUT;     //Als Ausgang&lt;br /&gt;
    GPIOD_InitStructure.GPIO_OType = GPIO_OType_PP;    //Push-Pull Betrieb&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Pin = GPIO_Pin_15;        //Pin 15 (STM32F4-Discovery: Blaue LED)&lt;br /&gt;
    GPIOD_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;  //Kein Pull-Up oder Pull-Down Widerstand aktiviert&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Speed = GPIO_Speed_25MHz; //25MHz Update-Rate&lt;br /&gt;
    GPIO_Init(GPIOD, &amp;amp;GPIOD_InitStructure);&lt;br /&gt;
&lt;br /&gt;
    GPIO_SetBits(GPIOD, GPIO_Pin_15);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hier ist noch ein &amp;quot;BasicFramework&amp;quot;, dass die komplette CMSIS- und Standard-Peripheral-Library enthält und kann Quasi als Basis für alle Projekte verwendet werden. Allerdings ist das Framework primär auf die STM32F405/7 und STM32F415/7 ausgelegt. Die neueren STM32F401, STM32F42X und STM32F43X  haben noch etwas andere Peripherie, dass Framework müsste dann entsprechend angepasst werden. Download: [[Datei:StdPeriphDriver_BasicFramework.zip]]&lt;br /&gt;
&lt;br /&gt;
===Einbinden der DSP-Library===&lt;br /&gt;
STM32F3 / STM32F4 Microcontroller haben neben der FPU noch einen Digital-Signal-Processor (DSP). Die DSP dient hauptsächlich dazu, viele Daten schnell zu verarbeiten (z.B. Video- oder Audiosignal). Der CMSIS-Download beinhaltet dazu neben der eigentlichen CMSIS-Library auch noch eine DSP-Library. Diese Library stellt sowohl einfache, mathematische Funktionen wie addieren, multiplizieren usw. als auch komplexe Funktionen, wie z.B  einen IIR-Filter, zur Verfügung. Die DSP-Library ist weiter aufgeteilt in kleinere Module, wie z.B. BasicMathFunctions, FilteringFunctions usw. (siehe &#039;&#039;&#039;&#039;&#039;CMSIS\DSP-Library\Source&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
*1. Source-Dateien des benötigten Moduls zum Projekt hinzufügen. (&#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Add files...&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
*2. &#039;&#039;&#039;&#039;&#039;arm_math.h&#039;&#039;&#039;&#039;&#039; in der &#039;&#039;&#039;&#039;&#039;main.c&#039;&#039;&#039;&#039;&#039; einbinden&lt;br /&gt;
*3. Damit die Warnung &amp;quot;Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)&amp;quot; verschwindet, muss der Define &#039;&#039;&#039;&#039;&#039;__FPU_PRESENT&#039;&#039;&#039;&#039;&#039; hinzugefügt werden. (Keine Ahnung, wieso es die Warnung gibt)&lt;br /&gt;
 &lt;br /&gt;
Jetzt kann die DSP-Library verwedet werden. Das Beispiel multipliziert zwei Buffer miteinander. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
#include &amp;quot;arm_math.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    float32_t x[1024];&lt;br /&gt;
    float32_t y[1024];&lt;br /&gt;
    float32_t z[1024];&lt;br /&gt;
&lt;br /&gt;
    for(uint16_t i = 0; i &amp;lt; 1024; i++)&lt;br /&gt;
    {&lt;br /&gt;
        x[i] = i;&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for(uint16_t i = 0; i &amp;lt; 1024; i++)&lt;br /&gt;
    {&lt;br /&gt;
        y[i] = PI;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    arm_mult_f32(x, y, z, 1024);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Startup-Code, Linker-Script, Takt, FPU usw.==&lt;br /&gt;
===Startup-Code===&lt;br /&gt;
Em::Blocks fügt standardmäßig einen Startup-Code mit in das Projekt ein. Die wichtigsten Dinge die darin erledigt werden sind folgende:&lt;br /&gt;
&lt;br /&gt;
*Stack und Heap wird angelgt&lt;br /&gt;
*Die Vector-Table wird angelegt&lt;br /&gt;
*Ein Default Reset-Handler wird implementiert, dieser erledigt folgende aufgaben:&lt;br /&gt;
**Kopieren der definierten Daten aus dem Flash in den SRAM&lt;br /&gt;
**&#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; wird aufgerufen, wenn &#039;&#039;&#039;&#039;&#039;__NO_SYSTEM_INIT&#039;&#039;&#039;&#039;&#039; nicht definiert ist&lt;br /&gt;
**Sprung in die &#039;&#039;&#039;&#039;&#039;main()&#039;&#039;&#039;&#039;&#039; Funktion&lt;br /&gt;
*Allen anderen Interrupt-Handler wird eine Default-Funktion &#039;&#039;&#039;&#039;&#039;def_irq_handler&#039;&#039;&#039;&#039;&#039; mit einer &#039;&#039;&#039;&#039;&#039;while(1)&#039;&#039;&#039;&#039;&#039;-Schleife zugewiesen, falls kein anderer Interrupt-Handler existiert.&lt;br /&gt;
&lt;br /&gt;
Normalerweise muss am Startup-Code nichts verändert werden.&lt;br /&gt;
&lt;br /&gt;
===Linker-Script===&lt;br /&gt;
Em::Blocks stellt zwei fertige Linker-Scripts bereit, eins für die Ausführung des Programmes aus dem Flash (&#039;&#039;&#039;&#039;&#039;*_flash.ld&#039;&#039;&#039;&#039;&#039;), das andere für die Ausführung aus dem SRAM (&#039;&#039;&#039;&#039;&#039;*_sram.ld&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Normalerweise muss auch hier nichts geändert werden, es sei den Daten sollen in bestimmten Adressbereichen abgelegt werden (z.B. im Core-Coupled RAM), was ich später noch zum Tutorial hinzufüge.&lt;br /&gt;
&lt;br /&gt;
===Der Takt===&lt;br /&gt;
Jeder Controller oder Prozessor braucht einen Takt, indem er die einzelnen Maschinen-Befehle abarbeiten kann.&lt;br /&gt;
Bei den STM32 Mikrocontrollern kann dieser Takt aus verschiedenen Quellen kommen:&lt;br /&gt;
&lt;br /&gt;
1. High Speed Internal Oszillator (HSI)&lt;br /&gt;
&lt;br /&gt;
2. High Speed External Oszillator (HSE)&lt;br /&gt;
&lt;br /&gt;
3. Low Speed Internal Oszillator (LSI)&lt;br /&gt;
&lt;br /&gt;
4. Low Speed External Oszillator (LSE)&lt;br /&gt;
&lt;br /&gt;
5. Phase-Locked Loop (PLL) (generiert den Takt aus den ersten vier Taktquellen durch Teiler und Faktoren)&lt;br /&gt;
&lt;br /&gt;
Nach einem Reset wird der Controller aus der HSI Taktquelle versorgt (16MHz beim STM32F407VG). Um die voll Performance des Controllers zu erreichen muss die PLL verwendet werden, welche den Takt durch geschickte Teiler und Faktoren vervielfältigt, sodass am Ende der Controller mit der maximalen Taktfrequenz läuft. Die notwendige Initialisierung der PLL findet in der Funktion &#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; statt. Die PLL erzeugt zunächst einen Basistakt:&lt;br /&gt;
&lt;br /&gt;
PLL_VCO = (F_HSE / PLL_M) * PLL_N&lt;br /&gt;
&lt;br /&gt;
Aus diesem Takt wird dann der Takt für den Controller-Kern abgeleitet:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = PLL_VCO / PLL_P&lt;br /&gt;
&lt;br /&gt;
Und der Takt für SDIO / USB / RNG (48MHz):&lt;br /&gt;
&lt;br /&gt;
48MHz = PLL_VCO / PLL_Q&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Durch weiter Teiler werden, die Takte für die einzelnen Busse erzeugt, da diese nicht alle beliebig schnell betrieben werden dürfen.&lt;br /&gt;
&lt;br /&gt;
Genaue Angaben findet man zu dem jeweiligen Clock-System des Controllers im Reference Manual.&lt;br /&gt;
&lt;br /&gt;
Ein Blick in den &amp;quot;Kommentar-Header&amp;quot; verrät, dass von einem externen (HSE) Oszillator von 25MHz ausgegangen wird, der die PLL versorgen soll.&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((25MHz / PLL_M(25)) * PLL_N(336)) / PLL_P(2) = 168MHz&lt;br /&gt;
&lt;br /&gt;
Allerdings stimmt diese Rechnung natürlich nur, wenn wirklich ein 25MHz Quarz am Controller angeschlossen ist. Auf dem STM32F4-Discovery Board befindet sich aber nur ein 8MHz Quarz. Demnach gilt:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((8MHz / PLL_M(25)) * PLL_N(336)) / PLL_P(2) = 53.76MHz&lt;br /&gt;
&lt;br /&gt;
Der Controller läuft also nur mit 53.76MHz, wenn wie ober beschrieben ein Projekt erstellt wird. Allerdings kann dieses Problem durch ändern von den betroffen Defines behoben werden:&lt;br /&gt;
 &lt;br /&gt;
*Dazu geht man in die &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; Datei und passt zur Vollständigkeit erstmal die zum Controller passende Tabelle im &amp;quot;Kommentar-Header&amp;quot; an (Z.57f):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      HSE Frequency(Hz)                      | 8000000&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      PLL_M                                  | 8&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Danach passt man den PPL_M Define (Z.254) an:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/************************* PLL Parameters *************************************/&lt;br /&gt;
/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */&lt;br /&gt;
#define PLL_M      8&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Außerdem muss man den HSE_VALUE Define in der &#039;&#039;&#039;&#039;&#039;inc/stm32f4xx.h&#039;&#039;&#039;&#039;&#039; angepasst werden (Z.122):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#if !defined  (HSE_VALUE)&lt;br /&gt;
  #define HSE_VALUE    ((uint32_t)8000000) /*!&amp;lt; Value of the External oscillator in Hz */&lt;br /&gt;
&lt;br /&gt;
#endif /* HSE_VALUE */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine neue Berechnung zeigt:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((8MHz / PLL_M(8)) * PLL_N(336)) / PLL_P(2) = 168MHz&lt;br /&gt;
&lt;br /&gt;
Jetzt läuft der Controller mit maximaler Geschwindigkeit.&lt;br /&gt;
&lt;br /&gt;
Die Theorie wird durch folgendes Programm verifiziert. Der geviertelte System-Takt SYSCLK wir am Pin PC9 ausgegeben. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);&lt;br /&gt;
&lt;br /&gt;
    GPIO_InitTypeDef GPIOC_InitStructure;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Mode = GPIO_Mode_AF;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_OType = GPIO_OType_PP;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Pin = GPIO_Pin_9;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;&lt;br /&gt;
    GPIO_Init(GPIOC, &amp;amp;GPIOC_InitStructure);&lt;br /&gt;
&lt;br /&gt;
    RCC_MCO2Config(RCC_MCO2Source_SYSCLK, RCC_MCO2Div_4);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Die FPU===&lt;br /&gt;
====Allgemeines====&lt;br /&gt;
STM32F3 und STM32F4 Controller haben eine FPU.&lt;br /&gt;
Damit die FPU richtig verwendet wird, müssen normalerweise zwei Bedingungen erfüllt sein:&lt;br /&gt;
&lt;br /&gt;
1. Der Controller muss die FPU Hardware-seitig aktivieren&lt;br /&gt;
&lt;br /&gt;
2. Damit die FPU auch was zu tuen bekommt, müssen vom Compiler FPU-Instructions erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
Die Em::Blocks IDE verwendet standardmäßig die FPU, wenn eine Vorhanden ist. Hier wird die FPU Hardware-seitig aktiviert (&#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; Z.341):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* FPU settings ------------------------------------------------------------*/&lt;br /&gt;
  #if (__FPU_PRESENT == 1) &amp;amp;&amp;amp; (__FPU_USED == 1)&lt;br /&gt;
    SCB-&amp;gt;CPACR |= ((3UL &amp;lt;&amp;lt; 10*2)|(3UL &amp;lt;&amp;lt; 11*2));  /* set CP10 and CP11 Full Access */&lt;br /&gt;
  #endif&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
__FPU_PRESENT wird in der &#039;&#039;&#039;&#039;&#039;stm32f4xx.h&#039;&#039;&#039;&#039;&#039; definiert.&lt;br /&gt;
__FPU_USED wird von der IDE übernommen (siehe Build-Log): &#039;&#039;&#039;&#039;&#039;-D__FPU_USED&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Außerdem wird der Compiler von der IDE standardmäßig mit dem Argument &#039;&#039;&#039;&#039;&#039;-mfloat-abi=hard&#039;&#039;&#039;&#039;&#039; aufgerufen, wodurch FPU-Instructions erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
====FPU abschalten====&lt;br /&gt;
Um die FPU ab zu schalten (Mir würde jetzt nur Strom sparen als Grund einfallen) geht man wie folgt vor:&lt;br /&gt;
&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; Device -&amp;gt; Policy&#039;&#039;&#039;&#039;&#039; wählt man &#039;&#039;&#039;&#039;&#039;Use target settings&#039;&#039;&#039;&#039;&#039; und über nimmt die Einstellungen, die vorher dort eingetragen waren, allerdings lässt man das Feld &#039;&#039;&#039;&#039;&#039;FP-hardware&#039;&#039;&#039;&#039;&#039; frei.&lt;br /&gt;
&lt;br /&gt;
[[Datei:fpu_1.png|FPU Abschalten Schritt 1]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;Compiler Settings -&amp;gt; Policy&#039;&#039;&#039;&#039;&#039; wählt man dann &#039;&#039;&#039;&#039;&#039;Use target options only&#039;&#039;&#039;&#039;&#039;. Dann kann man unter &#039;&#039;&#039;&#039;&#039;Categories&#039;&#039;&#039;&#039;&#039; die Option &#039;&#039;&#039;&#039;&#039;ARM FPU architecture&#039;&#039;&#039;&#039;&#039; auswählen. Dort stehen dann drei Möglichkeiten für die FPU zur Verfügung:&lt;br /&gt;
&lt;br /&gt;
1. Software-FPU-Library für Gleitkomma-Berechnung verwenden - Keine FPU-Instructions werden generiert (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=soft&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
2. Eine Mischung aus Software- und Hardware-FPU wird verwendet (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=softfp&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
3. Hardware-FPU wird für Gleitkomma-Berechnungen verwendet (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=hard&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
[[Datei:fpu_2.png|FPU Abschalten Schritt 2]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Um die FPU ab zu schalten wählt man natürlich die erste Möglichkeit.&lt;br /&gt;
Bei der 2. und 3. Möglichkeit fügt die IDE auch den Define &#039;&#039;&#039;&#039;&#039;__FPU_USED&#039;&#039;&#039;&#039;&#039; hinzu. Bei Der ersten Möglichkeit nicht. Der Code muss also nicht verändert / auskommentiert werden.&lt;br /&gt;
&lt;br /&gt;
Um die FPU wieder zu aktivieren müssen alle Schritte wieder rückgängig gemacht werden.&lt;br /&gt;
&lt;br /&gt;
Am besten ist es einfach mal alle Möglichkeiten im Einzelschritt durch zu probieren. Dann stellt man schnell fest, ob die FPU aktiviert wir oder nicht. Ein Blick in den erweiterten &#039;&#039;&#039;&#039;&#039;Build-Log&#039;&#039;&#039;&#039;&#039; gibt auch schnell Aufschluss darüber, wie der Compiler aufgerufen wird (siehe Kapitel [http://www.mikrocontroller.net/articles/STM32_-_Einstieg_mit_Em::Blocks#Compilieren Compilieren]).&lt;br /&gt;
&lt;br /&gt;
====Test Programm für die FPU====&lt;br /&gt;
Hier ein kleines Testprogramm, dass misst wie viele Taktzyklen für eine Gleitkomma-Multiplikation gebraucht werden. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define CORE_SysTickEn()    (*((u32*)0xE0001000)) = 0x40000001&lt;br /&gt;
#define CORE_SysTickDis()   (*((u32*)0xE0001000)) = 0x40000000&lt;br /&gt;
#define CORE_GetSysTick()   (*((u32*)0xE0001004))&lt;br /&gt;
&lt;br /&gt;
uint32_t t1, t2, dt;&lt;br /&gt;
float x, y, z;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    x = 53.64f;&lt;br /&gt;
    y = 0.27f;&lt;br /&gt;
&lt;br /&gt;
    CORE_SysTickEn();&lt;br /&gt;
    t1 = CORE_GetSysTick();&lt;br /&gt;
&lt;br /&gt;
    z = x * y;&lt;br /&gt;
&lt;br /&gt;
    t2 = CORE_GetSysTick();&lt;br /&gt;
    CORE_SysTickDis();&lt;br /&gt;
&lt;br /&gt;
    dt = (t2 - t1) - 9; //9 Takt-Zyklen werden für die Messung gebraucht &lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Core-Coupled-RAM verwenden===&lt;br /&gt;
Auf den normale SRAM kann durch den Core und die verschiedenen DMA-Controller zugegriffen werden. Jedoch können Core und DMA nicht gleichzeitig auf den SRAM zugreifen. Deswegen gibt es einen zweiten kleinen RAM, den Core-Coupled-RAM (CCRAM), auf den nur vom Core zugegriffen werden kann und nicht von einem DMA-Controller. Der CCRAM ist über einen anderen Bus an dem Cortex angeschlossen. Daduch wird ermöglicht, dass der Core sinnvoll weiterarbeiten kann, wenn ein DMA-Controller Daten aus den &amp;quot;Haupt&amp;quot;-RAM ließt/schreibt, indem der Core Daten aus dem CCRAM verarbeitet. Um Daten in den CCRAM zu legen, geht man wie folgt vor:&lt;br /&gt;
&lt;br /&gt;
1. Eine neue Section im Linkerscript anlegen:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
Sections:&lt;br /&gt;
{&lt;br /&gt;
  ...&lt;br /&gt;
&lt;br /&gt;
  .ccram :&lt;br /&gt;
  {&lt;br /&gt;
    *(.ccram)&lt;br /&gt;
  } &amp;gt; CCRAM&lt;br /&gt;
&lt;br /&gt;
  ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Um die neue Section zu verwenden benutzt man diesen Define:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#define CCRAM __attribute__((section(&amp;quot;.ccram&amp;quot;)))&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
int CCRAM dataInCCRAM;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Beim Debuggen stellt man fest das die Variable an der Adresse 0x10000000 liegt, der ersten Adresse das CCRAM&#039;s.&lt;br /&gt;
&lt;br /&gt;
==Booten aus dem SRAM==&lt;br /&gt;
STM32 Controller haben die Möglichkeit Code aus dem Flash als auch aus dem SRAM auszuführen. Um eine Anwenung per Debugger in des SRAM zu laden sind nur wenige Schritte erforderlich:&lt;br /&gt;
&lt;br /&gt;
*Um das Linkerscript für den SRAM zu verwenden geht man zu: &#039;&#039;&#039;&#039;&#039;Build options... -&amp;gt; Device&#039;&#039;&#039;&#039;&#039; dort wählt man unter &#039;&#039;&#039;&#039;&#039;Policy&#039;&#039;&#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;Use target settings&#039;&#039;&#039;&#039;&#039; aus und übernimmt die vorherigen Einstellungen, nur unter &#039;&#039;&#039;&#039;&#039;Linker script*&#039;&#039;&#039;&#039;&#039; gibt man &#039;&#039;&#039;&#039;&#039;.\stm32f407vg_sram.ld&#039;&#039;&#039;&#039;&#039; an&lt;br /&gt;
&lt;br /&gt;
*Dann muss man noch unter &#039;&#039;&#039;&#039;&#039;Debug -&amp;gt; Interfaces -&amp;gt; Settings&#039;&#039;&#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;Vector table start&#039;&#039;&#039;&#039;&#039; auf 0x20000000 ändern und &#039;&#039;&#039;&#039;&#039;Execute from RAM&#039;&#039;&#039;&#039;&#039; auswählen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:bootsram_1.png Booten aus dem SRAM]] [[Datei:bootsram_2.png Booten aus dem SRAM]]&lt;br /&gt;
&lt;br /&gt;
Anschließend kann man die Anwendung ganz normal debuggen. Nach einem Reset muss die Anwenung erneut mit dem Debugger gestartet werden.&lt;br /&gt;
&lt;br /&gt;
=Fortsetzung folgt..=&lt;br /&gt;
Kritik, Wünsche usw. sind gerne erwünscht, am besten hier in den Thread posten: [http://www.mikrocontroller.net/topic/323750 Neues STM32 Tutorial]&lt;br /&gt;
&lt;br /&gt;
[[Category:ARM]]&lt;br /&gt;
[[Category:STM32]]&lt;/div&gt;</summary>
		<author><name>Avrprogger</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=STM32&amp;diff=81889</id>
		<title>STM32</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=STM32&amp;diff=81889"/>
		<updated>2014-03-01T18:00:25Z</updated>

		<summary type="html">&lt;p&gt;Avrprogger: dfg&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;STM32 ist eine Mikrocontroller-Familie von [http://www.st.com/mcu/inchtml-pages-stm32.html ST] mit einer 32-Bit [http://www.arm.com/products/processors/cortex-m/index.php ARM Cortex-M0/M3/M4] CPU. Diese Architektur ist speziell für den Einsatz in Microcontrollern neu entwickelt und löst damit die bisherigen ARM7-basierten Controller weitestgehend ab. Den STM32 gibt es von ST in unzähligen Varianten mit variabler Peripherie und verschiedenen Gehäusegrößen und -formen. Durch die geringe Chipfläche des Cores ist es ST möglich, eine 32 Bit-CPU für weniger als 1&amp;amp;nbsp;€ anzubieten.&lt;br /&gt;
&lt;br /&gt;
[[Bild:stm32F103xc.png|thumb|right|340px|Blockdiagramm STM32F103xC/D/E]]&lt;br /&gt;
&lt;br /&gt;
== STM32-Familien ==&lt;br /&gt;
&lt;br /&gt;
Bisher gibt es sieben STM32-Familien:&lt;br /&gt;
* [http://www.st.com/internet/mcu/subclass/1588.jsp STM32F0]&lt;br /&gt;
** Cortex M0&lt;br /&gt;
** Mikrocontroller zum Einstieg&lt;br /&gt;
** Bis 48MHz&lt;br /&gt;
* [http://www.st.com/internet/mcu/subclass/1169.jsp STM32F1]&lt;br /&gt;
** Cortex M3&lt;br /&gt;
** Bis 72MHz&lt;br /&gt;
**Verschiedene Unterfamilien:&lt;br /&gt;
*** Connectivity line&lt;br /&gt;
*** Performance line&lt;br /&gt;
*** USB Access line&lt;br /&gt;
*** Access Line&lt;br /&gt;
*** Value line&lt;br /&gt;
* [http://www.st.com/web/en/catalog/mmc/FM141/SC1169/SS1575 STM32F2]&lt;br /&gt;
** Cortex M3&lt;br /&gt;
** Bis 120MHz&lt;br /&gt;
** Wie die STM32F1 Serie, Camera-Interface, 32-Bit Timer, Crypto-Engine...&lt;br /&gt;
* [http://www.st.com/internet/mcu/subclass/1605.jsp STM32F3]&lt;br /&gt;
** Cortex M4F&lt;br /&gt;
** DSP und FPU&lt;br /&gt;
** Bis 72MHz&lt;br /&gt;
** Fast 12-bit 5 MSPS and precise 16-bit sigma-delta ADCs&lt;br /&gt;
** Touch sensing controller (TSC)&lt;br /&gt;
* [http://www.st.com/internet/mcu/subclass/1521.jsp STM32F4]&lt;br /&gt;
** Cortex M4F&lt;br /&gt;
** DSP und FPU&lt;br /&gt;
** Bis 180MHz&lt;br /&gt;
** Bis zu 2MB Flash&lt;br /&gt;
* [http://www.st.com/web/en/catalog/mmc/FM141/SC1169/SS1295 STM32L1]&lt;br /&gt;
** Cortex M3&lt;br /&gt;
** Low Power &lt;br /&gt;
** mit LCD Treiber&lt;br /&gt;
** Bis 32MHz&lt;br /&gt;
* [http://www.st.com/web/en/catalog/mmc/FM141/SC1169/SS1581 STM32W]&lt;br /&gt;
** Cortex M3&lt;br /&gt;
** BIS 24MHz&lt;br /&gt;
** RF-MCU &lt;br /&gt;
[http://www.st.com/internet/mcu/class/1734.jsp Hier eine Übersicht zum Auswählen eines STM32Fxxx]&lt;br /&gt;
&lt;br /&gt;
===Features===&lt;br /&gt;
* Cortex-M0 / Cortex-M3 / Cortex-M4F Kern (mit FPU)&lt;br /&gt;
* 16KB ... 2MB  [[Flash-ROM]]&lt;br /&gt;
*  4KB ... 256KB [[Speicher#SRAM|SRAM]]&lt;br /&gt;
* 4KB [[Speicher#EEPROM|EEPROM]] (STM32L)&lt;br /&gt;
* SDRAM-Controller bei den [http://www.st.com/web/en/catalog/mmc/FM141/SC1169/SS1577/LN1806 STM32F42xxx und STM32F43xxx], bis 512 MByte externer SDRAM addressierbar&lt;br /&gt;
* 512 one-time programmable Bytes(STM32F2/4)&lt;br /&gt;
* [[IC-Gehäuseformen | Gehäuse]] 20 ... 216 Pins als TSSOP, QFN, LQFP und BGA&lt;br /&gt;
* Derzeit sind über &#039;&#039;&#039;250&#039;&#039;&#039; [http://www.st.com/web/en/catalog/mmc/FM141/SC1169 STM32 Derivate/Varianten verfügbar]&lt;br /&gt;
* Bis 72MHz CPU-Takt, bis 120MHz beim STM32F2xx, bis 168/180 MHz beim STM32F4xx, wobei eine spezielle prefetch-hardware bis 120/168 MHz eine Geschwindigkeit erzielen soll, die 0 Wait-States entspricht. Der CPU-Takt wird über einen Multiplikator aus dem internen RC-Takt oder einem externen Quarz-Takt abgeleitet.&lt;br /&gt;
* Externes Businterface (nur bei Gehäusen ab 100 Pin und nur bei STM32F4, STM32F2 und STM32F1 Performance line)&lt;br /&gt;
* LCD Treiber für 8x40 Punkte (nicht beim STM32F2xx)&lt;br /&gt;
* TFT Treiber bei STM32F429 / STM32F439&lt;br /&gt;
* Spannungsbereich 1,65 ... 3,6V, nur eine Betriebsspannung nötig&lt;br /&gt;
* Temperaturbereich bis 125 °C&lt;br /&gt;
* Bis zu 140 IOs, viele davon [[Pegelwandler|5V-tolerant]]&lt;br /&gt;
* Interner, kalibrierter RC-Oszillator mit 8MHz (16MHz bei STM32F2/F4xx)&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 (bei STM32F103xF/G), (bis zu 32 PWM Ausgänge)&lt;br /&gt;
* Systick Counter&lt;br /&gt;
* Bis zu 3 12-Bit [[AD-Wandler]] mit insgesamt 24 AD-Eingängen, integrierter [[Temperatursensor]], Referenzspannung Vrefint und VBatt Spannungsmessung (STM32F4xx)&lt;br /&gt;
* Bis zu 2 12-Bit [[DA-Wandler]] (bis zu 3 beim STM32F3xx)&lt;br /&gt;
* Bis zu 2 [[DMA]] Controller mit bis zu 12 Kanälen (16 beim STM32F2/4xx)&lt;br /&gt;
* Bis zu 2x [[I2C|I²C]]&lt;br /&gt;
* Bis zu 5x [[UART|USART]] mit LIN, IrDA und Modem Control (bis zu 8 beim STM32F2/F4xx)&lt;br /&gt;
* Bis zu 3x [[SPI]] (bis zu 6 beim STM32F4xx)&lt;br /&gt;
* Bis zu 2x [[I2S|I²S]]&lt;br /&gt;
* Bis zu 2x [[CAN#STMicroelectronics STM32 (Cortex M3/M4)|CAN]]&lt;br /&gt;
* Hardware [[CRC]] Unit, bei der STM32F3xx Serie mit einem einstellbaren Polynom &lt;br /&gt;
* Unique device ID register (96 Bits)&lt;br /&gt;
* RNG - Random Number Generator (STM32F2/4xx)&lt;br /&gt;
* Cryptographic Processor (CRYP) (STM32F2/4xx)&lt;br /&gt;
* Hash Processor (HASH) (STM32F2/4xx)&lt;br /&gt;
* Kamera-Interface (DCMI) (STM32F2/4xx)&lt;br /&gt;
* [[USB]] 2.0 Full Speed / OTG&lt;br /&gt;
* [[USB]] 2.0 Hi Speed OTG mit extra PHY-Chip (STM32F2/4xx)&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 [[Ultra low power|Strom sparen]] lässt&lt;br /&gt;
* [[JTAG]] und SWD (Serial Wire Debug) Interface&lt;br /&gt;
* Bis zu 6 Hardware-Breakpoints für Debuggen&lt;br /&gt;
* und vieles mehr . . .&lt;br /&gt;
&lt;br /&gt;
== Struktur der Dokumentation: ==&lt;br /&gt;
Die Dokumentation der STM32 ist zwar umfangreicher und komplexer z.B. die der [[AVR]], enthält aber dennoch alle nötigen Informationen. Sie teilt sich auf in mehrere Dokumente.&lt;br /&gt;
Als Beispiel der Dokumentation soll stellvertretend der [http://www.st.com/web/en/catalog/mmc/FM141/SC1169/SS1031/LN1565/PF164486 STM32F103RC] genannt werden. Die Seite von ST beinhaltet alle nötigen Informationen passend zu diesem Prozessor.&lt;br /&gt;
&lt;br /&gt;
Diese Dokumente von ST beschreiben den Controller:&lt;br /&gt;
&lt;br /&gt;
* Im [http://www.st.com/st-web-ui/static/active/en/resource/technical/document/datasheet/CD00191185.pdf STM32F103xC/D/E Datasheet] sind die speziellen Eigenschaften einer bestimmten Modellreihe beschrieben und die exakten Daten und Pinouts aufgeführt, sowie die Zuordnung Chipname - Flash/RAM-Größe. Die Peripheriemodule werden nur aufgeführt, nicht detailliert beschrieben.&lt;br /&gt;
* Im [http://www.st.com/st-web-ui/static/active/en/resource/technical/document/reference_manual/CD00171190.pdf Reference Manual (RM0008)] sind alle Peripheriemodule der jeweiligen STM32-Controllerfamilie im Detail beschrieben.&lt;br /&gt;
* Das [http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0403c/index.html ARMv7M Architecture Reference Manual] beschreibt detailliert den Prozessorkern, wie das Exception Model, die CPU Instruktionen inklusive Encoding, etc.&lt;br /&gt;
* Das [http://www.st.com/st-web-ui/static/active/en/resource/technical/document/programming_manual/CD00228163.pdf STM32 Cortex-M3 Programming Manual] ist eine Zusammenfassung des ARMv7M Architecture Reference Manual bezogen auf die STM32.&lt;br /&gt;
* Wer nicht die ST Firmware-Library verwendet, der benötigt zusätzlich das [http://www.st.com/st-web-ui/static/active/en/resource/technical/document/programming_manual/CD00283419.pdf Flash Programming Manual] für die Betriebsart des Flash-ROMs, d.h. die frequenzabhängige Konfiguration der Waitstates.&lt;br /&gt;
&lt;br /&gt;
Zusätzlich sollten auch die [http://www.st.com/st-web-ui/static/active/en/resource/technical/document/errata_sheet/CD00197763.pdf Errata Sheets] beachtet werden. Empfohlen sei auch die Appnote &amp;quot;[http://www.st.com/web/en/resource/technical/document/application_note/CD00164185.pdf AN2586 Getting started with STM32F10xxx hardware development]&amp;quot;.&lt;br /&gt;
Die jeweiligen Dokumentations-PDFs sind auf der Produktseite von ST eines jeden Mikrocontrollers verlinkt.&lt;br /&gt;
&lt;br /&gt;
== Hardware Zugriffs-Libraries ==&lt;br /&gt;
=== CMSIS ===&lt;br /&gt;
&lt;br /&gt;
Die CMSIS (ARM® &#039;&#039;&#039;C&#039;&#039;&#039;ortex™ &#039;&#039;&#039;M&#039;&#039;&#039;icrocontroller &#039;&#039;&#039;S&#039;&#039;&#039;oftware &#039;&#039;&#039;I&#039;&#039;&#039;nterface &#039;&#039;&#039;S&#039;&#039;&#039;tandard) ist eine Library von ARM für den Zugriff auf die herstellerübergreifenden Funktionen des ARM-Cores. Hierzu gehört bei den Cortex-M4F-Cores auch die DSP und Floating-Point Funktionalität. Weiterhin existieren eine Zahl von Helferfunktionen für den NVIC, den Sys-Tick-Counter, sowie eine SystemInit-Funktion, welche sich um die PLL kümmert. &lt;br /&gt;
&lt;br /&gt;
Im Rahmen des CMSIS-Standards ([http://www.onARM.com www.onARM.com]) wurden die Headerdateien standardisiert, der Zugriff auf die Register erfolgt per &#039;&#039;&#039;Peripheral-&amp;gt;Register&#039;&#039;&#039;. Die CMSIS C-Dateien bzw. Header enthalten auch Anpassungen für die verschiedenen Compiler. Die Portierung eines Real-Time-Betriebsystems sollte unter Verwendung der CMSIS, für Chips der verschiedenen Hersteller, stark vereinfacht möglich sein (z.B. einheitliche Adressen für Core-Hardware/Sys-Tick-Counter).&lt;br /&gt;
&lt;br /&gt;
Die CMSIS ist im Download der ‎STM32 Standard Peripheral Library enthalten. Die Compiler-Hersteller liefern eine jeweils zur ihrer Tool-Version passende bzw. geprüfte Library (incl. CMSIS) aus. Diese Libs können, gegenüber den Downloads beim Chip-Hersteller, auch ältere Version beinhalten.&lt;br /&gt;
&lt;br /&gt;
=== ‎STM32 Standard Peripheral Library ===&lt;br /&gt;
&lt;br /&gt;
ST bietet für jede Controller-Familie eine umfangreiche zur CMSIS passende Peripherie-Bibliothek. Alle Funktionen um die Peripherie zu benutzen sind gekapselt in einfache Strukturen und Funktionsaufrufe. Somit muss man sich nicht selbst um die Peripherie-Register kümmern. Diese Library und ihre Dokumentation setzen das grundlegende Verständnis der Funktion des jeweiligen Peripheriemoduls voraus, wie es die o.a. Referenz und diverse Appnotes vermitteln. Die Library beinhaltet außerdem für fast jede Peripherie mehrere Beispiele.&lt;br /&gt;
Für die USB Schnittstelle gibt es noch eine extra Library, genauso wie für Ethernet.&lt;br /&gt;
&lt;br /&gt;
Auf der &amp;quot;Design Resources&amp;quot; Seite der Produktseite von ST eines jeden STM32 Mikrocontrollers kann die Library für den jeweiligen Controller heruntergeladen werden, z.B. [http://www.st.com/web/en/catalog/tools/PF257890 hier für den o.g. STM32F103RC].&lt;br /&gt;
&lt;br /&gt;
Library für STM32F4xx: [http://www.st.com/web/en/catalog/tools/PF257901# STSW-STM32065 STM32F4 DSP and standard peripherals library]&lt;br /&gt;
&lt;br /&gt;
== Programmierung ==&lt;br /&gt;
Zur Programmierung der STM32 gibt es verschiedene Möglichkeiten, sowohl kommerzielle proprietäre als auch mit Freier Software.&lt;br /&gt;
&lt;br /&gt;
Der GCC (in seinen verschiedenen Binärdistributionen) ist der einzige ARM Compiler der [http://de.wikipedia.org/wiki/C%2B%2B11 C++11] unterstützt.&lt;br /&gt;
&lt;br /&gt;
=== Freie Software/Freeware ===&lt;br /&gt;
==== Selber zusammenstellen ====&lt;br /&gt;
Man nehme...:&lt;br /&gt;
* Eine Entwicklungsumgebung nach Wahl:&lt;br /&gt;
** [http://www.eclipse.org Eclipse] mit [http://www.eclipse.org/cdt/ C/C++ Development Tooling] und [http://gnuarmeclipse.livius.net/blog/ GNU ARM Plug-in] (Bei Verwendung vom GCC-ARM-Embedded als Toolchain &amp;quot;Sourcery G++ Lite&amp;quot; auswählen, dieser sieht für eclipse gleich aus) (Linux, Windows)&lt;br /&gt;
** [http://netbeans.org/ Netbeans] mit [http://plugins.netbeans.org/plugin/37426/gdbserver GDBserver-Plugin] (Linux, Windows)&lt;br /&gt;
** [http://www.kdevelop.org/ KDevelop] (Linux)&lt;br /&gt;
** [http://www.geany.org/ Geany] (Linux, Windows)&lt;br /&gt;
** Oder ein einfacher Texteditor&lt;br /&gt;
* Einen C,C++ Compiler:&lt;br /&gt;
** Eine der [[ARM_GCC#GCC_Bin.C3.A4rdistributionen|GCC-Binärdistributionen]], siehe auch [[#GCC|GCC]] (je nach Distribution Linux, Windows)&lt;br /&gt;
* Programmiersoftware zum Flashen des Target:&lt;br /&gt;
** [http://openocd.sourceforge.net/ OpenOCD] unterstützt viele Debug/Programmier-Adapter (Linux, Windows)&lt;br /&gt;
** [https://github.com/texane/stlink Texane stlink] funktioniert gut mit den ST-Link Adaptern wie sie zB. auf den STM32 Discovery Boards zu finden sind (Linux)&lt;br /&gt;
** Turtelizer2 oder andere JTAG Programmieradapter&lt;br /&gt;
** Bei Verwendung eines Segger J-Link, den [http://www.segger.com/admin/uploads/productDocs/UM08005_JLinkGDBServer.pdf Segger GDB-Server] in Verbindung mit dem beim GCC mitgelieferten GDB (Linux, Windows)&lt;br /&gt;
&lt;br /&gt;
==== Komplette IDE&#039;s ====&lt;br /&gt;
* [http://www.codesourcery.com/sgpp/lite_edition.html Codesourcery Lite Edition]&lt;br /&gt;
* [http://www.coocox.org/ Coocox Eclipse IDE] kostenlose IDE für STM32F0 / F1 / F4 Hilfreiche Infos gibt es im [http://www.mikrocontroller.net/topic/214719?goto=new#2228482 hier] und [http://www.mikrocontroller.net/topic/214719?goto=new#2229943 hier] Forum, Artikel: [[STM32 CooCox Installation]] &lt;br /&gt;
* [http://emide.org/ emIDE] kostenlose IDE die mit dem Segger J-LINK funktioniert.&lt;br /&gt;
* [http://www.emblocks.org EmBlocks] kostenlose IDE, Code::Blocks basiert, unterstützt STM32 L1/F0/F1/F2/F3/F4/W, integrierter Compiler (ARM-GCC), integrierter GDB Debugger, Jlink/ST-Link, System view (Peripherie Register anzeigen) beim Debuggen, Project Wizard (Eigene Wizards können mit Squirrel geschreiben werden), Basiert auf Code::Blocks, [http://www.mikrocontroller.net/articles/STM32_-_Einstieg_mit_Em::Blocks STM32 - Einstieg mit Em::Blocks]&lt;br /&gt;
&lt;br /&gt;
=== Kommerzielle Umgebungen ===&lt;br /&gt;
&lt;br /&gt;
* [http://www.keil.com/arm/mdk.asp Keil µVision] (Demo max. 32KB Code): Die sehr komfortable µVison IDE ist neben dem ARM Compiler per Menue auch für einen beliebigen GNU-Compiler konfigurierbar. Damit besteht das 32k-Limit nur noch für den integrierten Debugger / Simulator. µVison selbst kann kostenlos mit dem MDK-Evaluationkit heruntergeladen werden. [https://www.keil.com/arm/demo/eval/arm.htm#DOWNLOAD download]&lt;br /&gt;
* [http://www.iar.com/en/Products/IAR-Embedded-Workbench/ IAR-Embedded-Workbench] (Demo max. 32KB Code) [http://supp.iar.com/Download/SW/?item=EWARM-EVAL download]&lt;br /&gt;
* [http://www.isystem.com/products/itag winIDEAiTag] Keine Code Limitierung, GCC und Testwerkzeug beinhaltet. Läuft mit dem iTag Adapter.&lt;br /&gt;
* [http://www.raisonance.com Raisonance Ride7] (GCC Compiler, kostenlose Version auf Debugging von max. 32KB Code limitiert, keine Limitierung beim Complilieren)&lt;br /&gt;
* [http://www.atollic.com Atollic] (Lite Version (bis V2.3.0) ohne Code-Limit, auf GCC basierend. Die neueste Version ab V3 hat fast keine Beschränkungen mehr außer jetzt einen Code-Limit von 32kB. Außerdem werden jetzt die meisten ARM Familien unterstützt. )&lt;br /&gt;
* [http://www.rowley.co.uk/arm/ Rowley Crossworks] (Demo 30 Tage unbeschränkt, 150$ für nichtkommerzielle Nutzung, auf GCC basierend)&lt;br /&gt;
* [http://www.code-red-tech.com Code Red] (GCC basierend)&lt;br /&gt;
* [http://www.sisy.de/index.php?id=17&amp;amp;no_cache=1 SiSy ARM oder SiSy Micrcontroller++] (Demo verfügbar keine Gößenbegrenzung, basiert auf GNU-Compiler, grafische Programmierung mit UML möglich, integrierter Debugger)&lt;br /&gt;
* [http://www.comsytec.eu/epsdebugger.php EPS Debugger Plugin, für STM32 Development mit Code::Blocks]&lt;br /&gt;
&lt;br /&gt;
=== Tutorials für diverse Tool-Kombinationen ===&lt;br /&gt;
[[STM32 Eclipse Installation|Windows,Linux, Eclipse + Yagarto/CodeSourcery + OpenOCD/ST-Link]]&lt;br /&gt;
&lt;br /&gt;
* Windows&lt;br /&gt;
** Eclipse&lt;br /&gt;
*** [http://www.mikrocontroller.net/topic/216554 Windows, Eclipse, codesourcery, st-link ]&lt;br /&gt;
*** [http://www.firefly-power.de/ARM/debugging.html Eclipse Plugin &amp;quot;GDB Hardware Debugging&amp;quot; mit OpenOCD]&lt;br /&gt;
** Code::Blocks&lt;br /&gt;
*** [http://www.mikrocontroller.net/topic/265600 Windows, Code::Blocks, STM32F4]&lt;br /&gt;
** STM32 mit EmBlocks&lt;br /&gt;
*** [http://www.emblocks.org/web/downloads-main Download EmBlocks]&lt;br /&gt;
*** [https://www.youtube.com/watch?v=coHPJylnzC8 Video STM32 Project Wizzard in EmBlocks]&lt;br /&gt;
** Atollic TrueSTUDIO&lt;br /&gt;
*** [[STM32 LEDBlinken AtollicTrueStudio|Atollic TrueSTUDIO Installation + Demo]]&lt;br /&gt;
** MDK-ARM Lite mit Einstellungen für STM32F0/F4-Discovery Board&lt;br /&gt;
*** [https://www.keil.com/demo/eval/arm.htm KEIL MDK-ARM Download]&lt;br /&gt;
*** [https://www.youtube.com/watch?v=RXOOxby5nns&amp;amp;list=PL6-W3FoUyb48WFI5PQv3SDJj2G1t2FonV&amp;amp;index=1 Installations Video STM32F4 Discovery Board]&lt;br /&gt;
*** [https://www.youtube.com/watch?annotation_id=annotation_203294&amp;amp;feature=iv&amp;amp;index=4&amp;amp;list=PL6-W3FoUyb48WFI5PQv3SDJj2G1t2FonV&amp;amp;src_vid=sN4gDZ7H8gw&amp;amp;v=BeZcQjXxk9A Einstellungen STM32F0 Discovery Board Video]&lt;br /&gt;
** SiSy ARM, STM32&lt;br /&gt;
*** Download: [http://www.sisy.de/index.php?id=59 SiSy DEMO] kein Begrenzung der Codegröße&lt;br /&gt;
*** [http://www.youtube.com/watch?v=84Y3jYLWYpo Videobeispiel]&lt;br /&gt;
** Microsoft Visual Studio&lt;br /&gt;
*** [http://visualgdb.com/tutorials/arm/stm32/f4_discovery/ &amp;quot;STM32F4-Discovery tutorial with Visual Studio&amp;quot;]&lt;br /&gt;
* Ubuntu&lt;br /&gt;
** [http://www.seng.de/downloads/HowTo_ToolChain_STM32_Ubuntu.pdf Ubuntu, eclipse, Code Sourcery, OpenOCD] ([http://www.seng.de/downloads/HowTo_ToolChain_STM32_Ubuntu.odt Das Gleiche im bearbeitbaren ODT-Format])&lt;br /&gt;
** [http://fun-tech.se/stm32/index.php Ubuntu, Selbstcompilierter GCC, STM32/Cortex-M3]&lt;br /&gt;
** [http://thetoolchain.com The ToolChain] - Automatisch installierende Entwicklungsumgebung mit eigenen und externen Treibern, Unterstützt QtCreator als IDE, Flexibel erweiterbar über Shellskripte&lt;br /&gt;
&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/214719 Tipps für Installation mit Eclipse]&lt;br /&gt;
&lt;br /&gt;
===Programmieradapter===&lt;br /&gt;
* [http://www.segger.com/jlink-model-overview.html SEGGER J-LINK / J-TRACE] für u.a. alle ARM7/9/11, Cortex-M0/M1/M3/M4/A5/A8/A9/R4 als [http://www.segger.com/cms/j-link-edu.html NonComercial] J-LINK-EDU für ca. 60,- zu haben, läuft in µVision, IAR, GDB (Linux &amp;amp; Windows über einen eigenen [http://www.segger.com/admin/uploads/productDocs/UM08005_JLinkGDBServer.pdf GDB-Server]), Keil, ...&lt;br /&gt;
* Keil [http://www.keil.com/ulinkme/ ULINK-ME], [http://www.keil.com/arm/ulink2/ ULINK2], [http://www.keil.com/arm/ulinkpro/ ULINK pro]&lt;br /&gt;
* [http://www.st.com/internet/evalboard/product/219866.jsp ST-LINK], [http://www.st.com/internet/evalboard/product/251168.jsp ST-LINK/V2]&lt;br /&gt;
* Jedes STM32 Discovery board hat einen ST-Link für Programmierung/Debugging per SWD on-board, welcher auch für eigene STM32 Target Hardware benutzt werden kann (ca. 12,- bis 19,-€, je nach Typ).&lt;br /&gt;
* [http://www.raisonance.com/~rlink-debugger-programmer__microcontrollers__tool~tool__T018:4cn9ziz4bnx6.html Raisonance RLink]&lt;br /&gt;
* [http://www.amontec.com Amontec] (Achtung: keine Reaktion auf Bestellung, Telefon, Email...)&lt;br /&gt;
* [http://www.hjtag.com H-JTAG] Personal Edition für ca. 60,- zu haben, läuft mit ADS, SDT, IAR, Vision und RVDS &lt;br /&gt;
* [http://www.isystem.com/products/itag iTag] für 50.- bei Amazon zu bestellen, oder als Eigenbau version (offenes Design) läuft mit der freien winIDEAiTag version (siehe oben)&lt;br /&gt;
&lt;br /&gt;
In der Regel haben die [[JTAG]] Adapter einen 20-Poligen Stecker, den man direkt auf die Demo-Boards, die auch einen 20-Poligen [[JTAG]]-Anschluss haben, einstecken kann. Die Pinbelegung ist genormt, siehe Artikel [[JTAG]]. Die Discovery-Boards haben keinen seperaten JTAG-Stecker, aber zumindest für das STM32F4 Discovery kann man sich leicht einen Adapter Pinheader-&amp;gt;JTAG Stecker selber bauen.&lt;br /&gt;
&lt;br /&gt;
Andere [[JTAG]] Adapter wie z.B. der ULink von Keil funktionieren nur mit dem Keil Compiler.&lt;br /&gt;
&lt;br /&gt;
===Programmieradapter Open-Source===&lt;br /&gt;
&lt;br /&gt;
* [https://www.olimex.com/Products/ARM/JTAG/ARM-JTAG-COOCOX/ ARM-JTAG-COOCOX], CoLinkEX Nachbau von Olimex, unterstützt JTAG sowie SWD&lt;br /&gt;
** [http://www.coocox.org/colinkEx.htm unterstützte uC]&lt;br /&gt;
** unterstütze IDEs: [http://www.keil.com/arm/mdk.asp Keil MDK-ARM 4.03] oder neuer, [http://www.iar.com/en/Products/IAR-Embedded-Workbench/ IAR Embedded Workbench 5.xx] oder neuer sowie die [http://www.coocox.org/CooCox_CoIDE.htm CooCox CoIDE]&lt;br /&gt;
* [https://www.olimex.com/Products/ARM/JTAG/ Olimex] ARM-USB-OCD (ca. 60.-, hat zusätzlich einen Spannungsausgen und einen COM Port)&lt;br /&gt;
* [http://www.oocdlink.com/ OOCDLink]&lt;br /&gt;
* [https://github.com/texane/stlink Stlink]&lt;br /&gt;
* [http://www.randomprojects.org/wiki/Floss-JTAG FLOSS-JTAG]&lt;br /&gt;
* [http://capitanio.org/mlink/ Linux Demo Code für die Discovery&#039;s ST-Link Programmierung]&lt;br /&gt;
&lt;br /&gt;
Der Controller hat auch einen fest eingebauten Boot-Lader. Damit läßt er sich auch über eine gewöhnliche serielle Schnittstelle programmieren, ohne dass man einen JTAG-Adapter benötigt. Dies erfordert ggf. entsprechende Konfiguration über die BOOTx-Pins und/oder die Option-Bytes.&lt;br /&gt;
&lt;br /&gt;
=== Demo-Projekte ===&lt;br /&gt;
&lt;br /&gt;
* Einführung in die GPIO Programmierung der STM32F10x und STM32F30x Prozessoren am Beispiel des STM32F3 Discovery Boards und Vergleich zur AVR IO Registerstruktur [http://www.mikrocontroller.net/topic/300472#new]&lt;br /&gt;
* [[prog_bsp_timer_1_timer2|Programmbeispiel für die Verwendung von Timer2 zusammen mit dem Interrupt]]&lt;br /&gt;
* [http://www.firefly-power.de/ARM/printf.html Printf() debugging mit minimalem Aufwand]&lt;br /&gt;
* [[STM32_BLDC_Control_with_HALL_Sensor|Programmbeispiel für BLDC Motoransteuerung (Timer 1) mit HALLSensor (Timer 3)]]&lt;br /&gt;
* [[Cortex_M3_OCM3U]]&lt;br /&gt;
* Martin Thomas hat ein umfangreiches Projekt erstellt, in der die Eclipse Einstellungen enthalten sind:&lt;br /&gt;
** [http://www.siwawi.arubi.uni-kl.de/avr_projects/arm_projects/arm_memcards/index.html &amp;quot;ChaN&#039;s FAT-Module with STM32 SPI&amp;quot;]&lt;br /&gt;
* [[STM32 USB-FS-Device Lib]]&lt;br /&gt;
* Modellbau-Sender auf STM32-Basis mit vielen Treibern [http://www.rcos.eu www.rcos.eu]&lt;br /&gt;
* Ausführliches [https://github.com/jkerdels/stm32edu Einstiegs-Tutorial] in Codeform für das [http://www.st.com/internet/evalboard/product/252419.jsp STM32F4 discovery board]&lt;br /&gt;
* [http://www.redacom.ch/keillab/ Schweizer Gondelbahnsteuerung über Webserver auf ETT STM32F ARM KIT Board in Keil RTOS] mit Webcam&lt;br /&gt;
* Die [http://ethernut.svn.sourceforge.net/viewvc/ethernut/trunk/ Ethernut SVN Version] unterstützt inzwischen viele STM32 Typen, viele Devices und einige STM32 Demoboards&lt;br /&gt;
* [http://mikrocontroller.bplaced.net/wordpress/?page_id=744 Uwe Bonnes&#039; Libraries für den STM32F4]&lt;br /&gt;
* [http://mikrocontroller.bplaced.net/wordpress/?page_id=3290 Uwe Bonnes&#039; STM32F429 Discovery Board Oszilloskop], hier der [http://www.mikrocontroller.net/topic/319831#new Thread]&lt;br /&gt;
&lt;br /&gt;
== Debug- und Trace-Interface (CoreSight™ Debug and Trace Technologie)==&lt;br /&gt;
&lt;br /&gt;
Übersicht über beide Funktionalitäten und den Schnittstellen:&lt;br /&gt;
http://www.keil.com/support/man/docs/ulink2/ulink2_cs_core_sight.htm&lt;br /&gt;
&lt;br /&gt;
Die Coresight-Debug-Architektur ermöglicht ein nicht-invasives Debugging, d.h. es können während des Betriebes (meistens) ohne Beeinflussung des Prozessors Daten vom Speicher gelesen und in selbigen geschrieben werden.&lt;br /&gt;
&lt;br /&gt;
=== Debugger Funktionen ===&lt;br /&gt;
&lt;br /&gt;
Der Debugger-Teil besitzt drei Funktionen:&lt;br /&gt;
* Run Control: z.B. Programm-Start, Stopp und Einzel-Schritte.&lt;br /&gt;
* (Program) Break Points: Ein Programm hält an, wenn der Programm Counter eine bestimmte Programm-Adresse erreicht.&lt;br /&gt;
** Die maximale Anzahl der gleichzeitig möglichen Break Points ist begrenzt (z.B. 6 bei einem STM32).&lt;br /&gt;
** Die Anzahl der Break Points ist nahezu unbegrenzt, wenn ein Debugger über den Memory Access (s.u.) sogenannte Flash Break Points unterstützt. Dabei wird ein geladenes Programm im Flash umprogrammiert, um den Debugger anzuhalten. Diese Funktionalität ist meistens ein kostenpflichtiges Zusatz-Feature des Debugger-Herstellers. &lt;br /&gt;
** Beinhaltet keine Data Watch Funktionalität, welche im Trace-Teil (DWT) realisiert wird.&lt;br /&gt;
* Memory Access: Lesen und Schreiben von Speicheradressen. &lt;br /&gt;
** Diese Funktionalität beinhaltet keine direkte Flash-Programmierung. Der Programmiervorgang für einen Flash ist herstellerspezifisch und muss von dem verwendeten Debugger unterstützt werden.&lt;br /&gt;
&lt;br /&gt;
=== Trace Funktionen ===&lt;br /&gt;
Die Trace-Funktionalität wird in drei Funktionen aufgeteilt:&lt;br /&gt;
* ETM (Embedded Trace Macrocell): Optional, nicht jede CPU besitzt diese Hardware (Kostenfaktor, Austattung).&lt;br /&gt;
* ITM (Instrumentation Trace Macrocell): Über diesen Kanal kann ein vereinfachtes Trace des Core ermöglicht werden, sowie &amp;quot;printf-ähnlich&amp;quot; Daten über den ITM Channel 0 geschickt und im Debugger ausgegeben werden.&lt;br /&gt;
* DWT (Data Watchpoint &amp;amp; Trace Unit): &lt;br /&gt;
** Data Watch: 4 Access-Break-Points ( z.B. der Debugger bleibt stehen, wenn das Programm auf einen Speicher zugreift oder der Wert einer Variablen einen bestimmten Wert annimmt). &lt;br /&gt;
** Trace Unit: Programmverlauf (durch Lesen des Program Counters) und Interrupt Aufrufe verfolgen, sowie Zeitmessungen.&lt;br /&gt;
&lt;br /&gt;
Einige der Trace-Funktionalitäten können über die JTAG-Schnittstelle angesprochen werden. Die schnelle Trace-Funktionalität (mit 4 bit Parallel-Port) steht nur mit der erweiterten DEBUG + ETM Schnittstelle zur Verfügung. Im Gegensatz zum Debugger-Teil (Run Control, Break Points und Memory Access) werden Trace-Funktionen nicht von allen Debuggern unterstützt. Debugger mit der vollen Trace-Funktionalität kosten deutlich mehr.&lt;br /&gt;
&lt;br /&gt;
* Beispiele für Trace-Port-Aktivierungen für verschiedene Hersteller: http://www.keil.com/support/man/docs/jlink/jlink_capture_tracedata.htm&lt;br /&gt;
&lt;br /&gt;
Die Aktivierung des parallelen Trace-Ports erfordert, je nach CPU Hersteller, zusätzliche Debugger-Makros für die Aktivierung und Port-Freischaltung. Zusätzlich sind die Schnittstellenauswahl und Einstellung (Frequenzen) im Entwicklungs-Tool (IDE) wichtig, um erfolgreich den Programm-Verlauf &amp;quot;tracen&amp;quot; zu können.&lt;br /&gt;
&lt;br /&gt;
=== Debug und Trace-Schnittstellen ===&lt;br /&gt;
Als Debug Interface stehen zwei Varianten zur Auswahl:&lt;br /&gt;
* [[JTAG]]: Dafür sind mindestens 6 Steuerleitungen nötig. Unterstützt Device Chaining: Mehrere verbundene Geräte können mit einem Debugger/Programmer gleichzeitig angesteuert werden.&lt;br /&gt;
* SWD (Serial Wire Debug): Hier mindestens 2  Steuerleitungen (3 mit SWO, zzgl GND und 3,3V). Die SWD Schnittstelle ist in der Regel schneller und kann auch Funktionen aus dem Trace-Teil beinhalten (z.B. ITM, dafür wird der SWO-Pin benötigt). Device Chaining ist mit dieser Schnittstelle nicht möglich.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Standard-JTAG Steckerbelegungen: &lt;br /&gt;
http://www.keil.com/support/man/docs/ulink2/ulink2_hw_connectors.htm&lt;br /&gt;
&lt;br /&gt;
=== Der 10polige JTAG-Stecker von mmvisual ===&lt;br /&gt;
mmvisual hat mit dieser Steckerbelegung die Standard JTAG Schnittstelle erweitert:&lt;br /&gt;
&lt;br /&gt;
Ich habe diesen Part in den Artikel [http://www.mikrocontroller.net/articles/JTAG#Der_10-polige_JTAG_Stecker_von_mmvisual JTAG] verschoben.&lt;br /&gt;
Hinzu gekommen ist die Adapterplatine 10-Polig auf Standard JTAG 20 Polig mit TTL/V24 Wandler. [http://www.mikrocontroller.net/articles/JTAG#Die_Adapterplatine Siehe hier.]&lt;br /&gt;
&lt;br /&gt;
== Hardware-Beschaltung ==&lt;br /&gt;
&lt;br /&gt;
Der STM32 benötigt für den Betrieb nur (Minimalbeschaltung):&lt;br /&gt;
&lt;br /&gt;
* VCC 2..3,3V (je nach Typ)&lt;br /&gt;
* AVCC 2..3,3V (sehr wichtig, der STM32 lässt sich ohne diese Spannung nicht programmieren)&lt;br /&gt;
* GND&lt;br /&gt;
* Reset Pin 100nF nach GND (ein Pull-Up Widerstand von ca. 40k ist intern vorhanden)&lt;br /&gt;
* [[#Bootmodi|Boot-Pins]]&lt;br /&gt;
&lt;br /&gt;
ansonsten nur ein paar einzelne Cs 100nF an VCC/GND.&lt;br /&gt;
&lt;br /&gt;
Um Programmieren zu können wird entweder noch die serielle Schnittstelle (Programmieren über den vorprogrammierten Bootloader) oder JTAG oder die SWD Schnittstelle benötigt.&lt;br /&gt;
&lt;br /&gt;
=== Bootmodi ===&lt;br /&gt;
Unterschiedliche Bootmodi lassen sich mittels der PINs BOOT0 und BOOT1 auswählen . Siehe Application Note [https://my.st.com/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Attachments/18225/AN2606.pdf AN2606]. Ausser F1 besitzen neuere Familien ein SYSCFG_MEMR Register. In dieses Register kann man die gewünschten Boot0/1 Werte schreiben und nach einem Core-Reset (!= System_Reset) startet der Prozessor im gewünschten Mode. Eine Neu- bzw. Deinitialisierung der Peripherie empfiehlt sich! &lt;br /&gt;
&lt;br /&gt;
==== Boot from FLASH ====&lt;br /&gt;
Startadresse wird von 0x08000004 geladen&lt;br /&gt;
 BOOT0 Lo&lt;br /&gt;
 BOOT1 X &lt;br /&gt;
&lt;br /&gt;
==== Boot from SRAM ====&lt;br /&gt;
PC Startadresse wird an 0x200001E0 direkt angesprungen.&lt;br /&gt;
 BOOT0 Hi&lt;br /&gt;
 BOOT1 Hi&lt;br /&gt;
Da der interne FLASH der stm32f1x laut Datenblatt nur für 1000 Schreibvorgänge ausgelegt ist, kann mittels BOOT0 (High) und BOOT1 (High) auch aus dem zuvor mit dem Debugger (JTAG/SWD) beschriebenen SRAM booten. &lt;br /&gt;
Hierbei gilt zu beachten:&lt;br /&gt;
 VTOR auf die NVIC Tabelle im SRAM vor dem auslösen des ersten Interrupts remappen.&lt;br /&gt;
&lt;br /&gt;
 Um ein vergleichbares Startverhalten zum FLASH zu erreichen, empfiehlt es sich,&lt;br /&gt;
 0xF1E0F85F an 0x200001E0 zu schreiben. Diese implizite Ausführung von &amp;quot;ldr.w pc,&lt;br /&gt;
 [pc, #-0x01E0]&amp;quot; beim Start erzwingt ein laden der Startadresse von 0x20000004.&lt;br /&gt;
&lt;br /&gt;
==== Boot from SYSMEM (RS232, CAN und USB) ====&lt;br /&gt;
PC Startadresse wird von 0x1FFFF004 geladen&lt;br /&gt;
 BOOT0 Hi&lt;br /&gt;
 BOOT1 Lo&lt;br /&gt;
&lt;br /&gt;
Ab F2 gibt es auch ein SYSCFG_MEMRMR Register. Schreibt man hier den Wert für &amp;quot;System Flash&amp;quot; und macht einen Corereset (keinen Systemreset), so landet ,man auch im Bootloader, unabhängig von dem wert der Boot Pins.&lt;br /&gt;
&lt;br /&gt;
Auch ohne JTAG lässt sich ein STM32 programmieren (Bootloader-Aktivierung). Dabei stehen, je nach CPU-Typ, verschiedene Möglichkeiten zur Verfügung:&lt;br /&gt;
* RS-232 (bisher alle STMs)&lt;br /&gt;
* USB (alle USB fähigen CPUs &amp;gt; F103)&lt;br /&gt;
* CAN (wie USB nur in bestimmten MCUs)&lt;br /&gt;
&lt;br /&gt;
3 zusätzliche Verbindungen müssen auf dem Board gepatcht werden. Für einen Test geht es auch mit Tastern für RESET und BOOT0.&amp;lt;br&amp;gt;&lt;br /&gt;
RESET=RTS (L-aktiv)&amp;lt;br&amp;gt;&lt;br /&gt;
BOOT0=DTR (H-aktiv)&amp;lt;br&amp;gt;&lt;br /&gt;
BOOT1=LOW&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Details sind hier im Forum: [http://www.mikrocontroller.net/topic/141711 STM32 Programmiertool]&lt;br /&gt;
&lt;br /&gt;
Tools für den Download über den STM32-Bootlaoder:&lt;br /&gt;
* [http://www.st.com/web/en/catalog/tools/PF257525 STSW-MCU005 STM32 and STM8 Flash loader demonstrator]&lt;br /&gt;
* [https://code.google.com/p/stm32flash/ Open source flash program for the STM32 ARM processors using the ST serial bootloader (for Linux)]&lt;br /&gt;
&lt;br /&gt;
== Bewertung ==&lt;br /&gt;
=== Vorteile ===&lt;br /&gt;
&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 Vektortabelle, keine Sprungliste 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 und eine besondere Konfiguration der Handler im Compiler entfällt. 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. Schön beschrieben ist es hier im [http://www.hitex.com/fileadmin/pdf/insiders-guides/stm32/isg-stm32-v18d-scr.pdf Insider&#039;s Guide] unter 2.4.5 / Seite 20.&lt;br /&gt;
* Thumb-2 Befehlssatz, deutlich schneller als Thumb-1 und ebenso kompakt&lt;br /&gt;
* Weniger Pins für Debugging benötigt durch SWD&lt;br /&gt;
* Mehr Hardware Breakpoints machen debuggen einfacher&lt;br /&gt;
* Software ist einfacher weil die Umschaltung zwischen ARM Mode und Thumb Mode wegfällt&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;
* FW-Lib für alle STM32 gleich, alle AppNotes/Demos beziehen sich auf diese eine FW-Lib was die Entwicklung der eigenen Applikation sehr beschleunigt.&lt;br /&gt;
* Genauerer und flexiblerer 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) Allerdings gibts den LPC1100 mit Cortex-M0 schon ab 0,65 $!&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Vorteile gegenüber SAM3/4:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Fast alle Pins sind 5-Volt tolerant.&lt;br /&gt;
&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;
* Schnelle direkte Offset-Adressierung ermöglich effizienten Zugriff auf Stack-Variablen, lokal gespeicherte Flash-Konstanten, struct/Array-Elemente&lt;br /&gt;
* Einfache einheitliche Adressierung des gesamten Adressraums, d.h. Pointer auf Peripherieregister, RAM &amp;amp; Flash können exakt gleich behandelt werden, keinerlei Banking/Umschalt-Mechanismen erforderlich auch bei großem Flash/RAM&lt;br /&gt;
* Interrupt-Prioritäten und Prioritätsgruppen&lt;br /&gt;
* Effiziente Pointerarithmetik da Registerbreite=Adressbreite&lt;br /&gt;
* bessere Peripherie wie USB, Ethernet, Vielzahl an Timern&lt;br /&gt;
* der ARM-Core hat eine höhere Taktfrequenz und kann gleichzeitig mehr in weniger Takten berechnen&lt;br /&gt;
* Hardware-Division, bei einigen FPU zur effizienten float-Berechnung&lt;br /&gt;
* Mit größerem Flash/RAM verfügbar&lt;br /&gt;
* Code kann direkt aus dem RAM ausgeführt werden, Speicherschutz und privilegierter Ausführungsmodus können &amp;quot;Kernel&amp;quot;- vor &amp;quot;Anwendungs&amp;quot;-Code schützen, somit wird das dynamische Nachladen von Anwendungen aus externem Speicher effizient &amp;amp; sicher möglich&lt;br /&gt;
* ... und weitere 1000 Punkte ...&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Links&#039;&#039;&#039;&lt;br /&gt;
* [http://www.arm.com/files/pdf/ARM_Microcontroller_Code_Size_%28full%29.pdf Code Size Analyse zwischen verschiedenen µC]&lt;br /&gt;
&lt;br /&gt;
=== Nachteile ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Nachteil gegenüber LPC1700:&#039;&#039;&#039;&lt;br /&gt;
* STM32F1xx: nur 72 MHz statt 100 MHz (LPC1759: 120 MHz) Taktfrequenz; STM32F2xx hat diesen Nachteil nicht (ebenfalls 120MHz, STM32F4xx mit 180MHz)&lt;br /&gt;
* Der LPC1700 besitzt deutlich mehr Mechanismen, um die Auswirkung der Waitstates des Flash-ROMs auf Code- und Datenzugriffe zu reduzieren und das bedeutet mehr Performance bei gleicher Taktfrequenz. Beim STM32F2 entfällt dieser Nachteil wohl aufgrund des ART Accelerators. &lt;br /&gt;
* Alle LPC1xxx haben 32 Bit Timer. Bei den STM32 haben das nur die STM32F2xx (2 Stück)&lt;br /&gt;
* I2S Einheit von ST hat keinen FIFO und im 24/32Bit Modus müssen 2x16Bit Halbwörter übertragen werden. Wobei allgemein bei neuen ARM Prozessoren die vorhandenen DMA-Kanäle (basierend auf eigenen BUS-Kanälen und Speicherzugriffen) FIFO in beliebiger Größe bedeutet. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Nachteil für Hobby-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. QFP64 in 0.5mm Pinabstand und nicht 0.8mm wie AVR. Von NXP gibt es Cortex-M0 µC im DIL Gehäuse.&lt;br /&gt;
&lt;br /&gt;
* Viel Peripherie, Clocks müssen alle richtig eingestellt werden, ggf. Anpassung des Startup Codes usw.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Errata, Tipps und Tricks ==&lt;br /&gt;
=== Hardware ===&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 9.3.3.: &amp;quot;CAN1 alternate function remapping&amp;quot;. Alle Infos von RM0008 9.3.x sind interessant&lt;br /&gt;
* CAN und USB sind bei der F1 Serie nur bei der &amp;quot;◦Connectivity-Line&amp;quot; gleichzeitig nutzbar. Siehe Datenblätter.&lt;br /&gt;
* Mit internem RC-Oszillator kann die CPU mit maximal 64MHz betrieben werden. Mit einem externen Quarz sind dann 72MHz möglich.&lt;br /&gt;
* Für USB Betrieb muss die CPU mit 48MHz oder 72MHz betrieben werden (bei STM32F1xx).&lt;br /&gt;
* Der Idle Interrupt vom Usart wird zwar ausgelöst, aber nicht vom entsprechenden Statusflag angezeigt&lt;br /&gt;
* Der DMA fängt beim aktivieren immer von vorn an zu zählen, auch wenn er nur kurz angehalten wurde&lt;br /&gt;
* STM32F2xx hat kein Flash Size Register, bei STM32F4xx ist zwar ein flash Size Register beschrieben, kollidiert aber in der Adresse mit einem anderen Register&lt;br /&gt;
* Derivate mit internem EEPROM und nur einer Speicherbank haben das &amp;quot;Feature&amp;quot; bei write/erase des Data-Flashes (EEPROM) einen kompletten stall der code execution zu verursachen (inkl. ISR&#039;s, DMA). Desgleichen bei write/erase des internen Flash (ISP-routinen, EEPROM-Emulation).&lt;br /&gt;
* Der I2C hat diverse Fehler, welche im Errata des jeweiligen Modells (z.B. [http://www.st.com/st-web-ui/static/active/en/resource/technical/document/errata_sheet/CD00238166.pdf STM32F105xx and STM32F107xx Errata sheet] ) zu finden sind. Workarounds hierzu finden sich in der Application Note [http://www.st.com/st-web-ui/static/active/en/resource/technical/document/application_note/CD00209826.pdf AN2824]. Am Besten benutzt man jedoch die I2C Communication peripheral application library (CPAL) von ST ([http://www.st.com/web/catalog/tools/FM147/CL1794/SC961/SS1743/PF258336 STSW-STM32127])&lt;br /&gt;
* [http://blog.frankvh.com/category/stm32/ weitere undokummentierte Features]&lt;br /&gt;
* Interrupt-Flags in Statusregistern der diversen Peripherals wie der Timer müssen zu &#039;&#039;&#039;Beginn&#039;&#039;&#039; (bzw. möglichst weit vor dem Return) der ISR zurückgesetzt werden, da die ISR sonst eventuell 2x ausgeführt wird ([http://www.mikrocontroller.net/topic/312393#new Siehe Forum]).&lt;br /&gt;
&lt;br /&gt;
=== Software ===&lt;br /&gt;
==== GCC ====&lt;br /&gt;
Um den GCC direkt zu verwenden (zB. mit selbstgebautem makefile), falls man das nicht von einer Entwicklungsumgebung machen lässt, siehe zunächst [[ARM GCC]]. STM32-spezifisches ist:&lt;br /&gt;
* Wird die [[#.E2.80.8ESTM32_Standard_Peripheral_Library|STM32 Standard Peripheral Library]] und ein Quarz verwendet, so muss noch per Präprozessor-Definition die Frequenz des Quarzes angegeben werden mittels z.B. -DHSE_VALUE=8000000 für 8MHz (wie auf dem STM32F4 Discovery).&lt;br /&gt;
&lt;br /&gt;
===== Startupcode &amp;amp; Linkerscript =====&lt;br /&gt;
* Damit der compilierte Code an den richtigen Stellen im Controller landet (d.h. dem Flash) muss man dem Linker ein Linkerscript mitgeben. Dies geht per &amp;quot;-T &#039;&#039;pfad_zum_linkerscript.ld&#039;&#039;&amp;quot; an den Linker-Befehl. Im Archiv der [[#.E2.80.8ESTM32_Standard_Peripheral_Library|STM32 Standard Peripheral Library]] befindet sich ein Beispiel-Linkerscript für die Atollic TrueSTUDIO IDE, dieses kann direkt mit dem GCC verwendet werden. Beispielsweise für den STM32F4 befindet sich das Script im Pfad &amp;quot;/STM32F4xx_DSP_StdPeriph_Lib_V1.1.0/Project/STM32F4xx_StdPeriph_Templates/TrueSTUDIO/STM324x7I_EVAL/stm32_flash.ld&amp;quot; des Archives.&lt;br /&gt;
* Damit beim Starten die richtigen Initialisierungen vorgenommen werden (wie globale Variablen und bei C++ Konstruktoren globaler Objekt-Instanzen) muss als erstes ein Startupcode laufen, der dann die main()-Funktion aufruft. Der Startupcode ist meistens in Assembler geschrieben, C-Code ist aber auch möglich. Im Archiv der [[#.E2.80.8ESTM32_Standard_Peripheral_Library|STM32 Standard Peripheral Library]] befindet sich ein Beispiel-Startupcode für die Atollic TrueSTUDIO IDE, dieser kann direkt mit dem GCC verwendet werden. Beispielsweise für den STM32F4 befindet sich der Code in Assemblerform im Pfad &amp;quot;/STM32F4xx_DSP_StdPeriph_Lib_V1.1.0/Libraries/CMSIS/Device/ST/STM32F4xx/Source/Templates/TrueSTUDIO/startup_stm32f40xx.s&amp;quot; des Archives. Der Assemblercode kann per arm-none-eabi-as (Flags s.o.) assemblisiert werden, die resultierende .o -Datei normal mitgelinkt.&lt;br /&gt;
&lt;br /&gt;
Zusammen bieten die beiden Dateien der Anwendung ein Standard-C-Interface, d.h. man kann wie gewohnt globale Variablen verwenden und seinen Code in die main()-Funktion schreiben.&lt;br /&gt;
&lt;br /&gt;
=== Tipps für Umsteiger von Atmel/PIC/8051 ===&lt;br /&gt;
* Prozessortakt hat unterschiedliche Taktquellen und eine PLL.&lt;br /&gt;
* Alle Peripheriemodule haben einen extra Clock, den man aktivieren muss.&lt;br /&gt;
* Wenn man z.B. einen UART benutzen möchte, so muss man den Clock vom UART, Alternate Function IO (AFIO) und dem GPIO-Port aktivieren.&lt;br /&gt;
* Ansonsten hat man nahezu doppelt so viele Möglichkeiten in den Peripheriemodulen.&lt;br /&gt;
* Interrupt-Flags müssen in der ISR selber gelöscht werden&lt;br /&gt;
* Forum zu [http://www.mikrocontroller.net/topic/175888 Interrupts vs. Events]&lt;br /&gt;
&lt;br /&gt;
=== Errata vom STM32F4xx die nicht im Errata von ST stehen ===&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/267439#2788478 Aktivieren von DMA], wenn mehr als 3 DMA Kanäle aktiviert werden, kann es sein dass die nicht alle korrekt bedient werden. Auch klappt der DMA mit dem FSMC nicht immer zuverlässig. [https://my.st.com/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Flat.aspx?RootFolder=%2Fpublic%2FSTe2ecommunities%2Fmcu%2FLists%2Fcortex_mx_stm32%2FWarning%20limit%20simultaneous%20DMAs%20to%202&amp;amp;FolderCTID=0x01200200770978C69A1141439FE559EB459D7580009C4E14902C3CDE46A77F0FFD06506F5B&amp;amp;currentviews=811 siehe hier] [http://blog.frankvh.com/2012/01/13/stm32f2xx-stm32f4xx-dma-maximum-transactions/ und hier]&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/260637#2700761 Nerviger Bug in &amp;quot;stm32f4xx.h&amp;quot;] Änderung Struktur GPIO_TypeDef&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/261690#2714754 Batterie wird leer gezogen], nur bei manchen Chips mit Rev. A&lt;br /&gt;
* [http://www.efton.sk/STM32/STM32F4xx_doc_errors.txt Liste von Dokumentations-Fehlern]&lt;br /&gt;
&lt;br /&gt;
== Bezugsquellen ==&lt;br /&gt;
&lt;br /&gt;
=== Controller ===&lt;br /&gt;
&lt;br /&gt;
Versandhäuser für Privatpersonen&lt;br /&gt;
* [http://www.reichelt.de/STM-Controller/2/index.html?;ACTION=2;LA=2;GROUPID=2950; Reichelt]&lt;br /&gt;
* [http://darisusgmbh.de/shop/index.php?cat=c2692_ARM-Cortex.html Darisus]&lt;br /&gt;
* [http://www.hbe-shop.de HBE (Farnell Programm für Private)] &lt;br /&gt;
* [http://www.sander-electronic.de/be00069.html Sander]&lt;br /&gt;
* [http://www.tme.eu/de/katalog/index.phtml#cleanParameters%3D1%26search%3DSTM32F10%26bf_szukaj%3D+ TME] &lt;br /&gt;
* [http://teske-electronics.de/index.php?cPath=3_9_53 Teske electronics]&lt;br /&gt;
* [http://de.rs-online.com/web/c/halbleiter/prozessoren-und-mikrocontroller/mikrocontroller/?sort-by=default&amp;amp;sort-order=default&amp;amp;applied-dimensions=4294417325&amp;amp;lastAttributeSelectedBlock=4294425895 RS-Online]&lt;br /&gt;
&lt;br /&gt;
Gewerblich liefern natürlich viele wie EBV, Mouser, Farnell, Digikey usw...&lt;br /&gt;
&lt;br /&gt;
=== Evaluation Boards ===&lt;br /&gt;
&lt;br /&gt;
* [http://shop.embedded-projects.net/index.php?module=artikel&amp;amp;action=gruppe&amp;amp;id=14 Im Shop von Embedded Projects]&lt;br /&gt;
* [http://www.watterott.com/de/Boards-Kits/ARM/ARM-Cortex-M3 Cortex M3 bei Watterott]&lt;br /&gt;
* [http://www.raisonance.com/~primer-starter-kits__microcontrollers__tool~tool__T018:4enfvamuxbtp.html Primer und Primer2 von Raisonance]&lt;br /&gt;
* [http://www.sander-electronic.de/es0028.html Sander Electronic]&lt;br /&gt;
* [http://www.mikrocontroller.net/articles/MP32F103-Stick:_Ein_Mini-Mikrocontroller-Board_mit_USB_und_bis_zu_4MB_Datenspeicher Artikel im Wiki, ARM mit USB und 4MB Speicher]&lt;br /&gt;
* [http://www.futurlec.com/STM32_Development_Board.shtml Futurlec Evalboard, ebenso Header-Board]&lt;br /&gt;
* [http://www.propox.com/products/t_174.html Propox, Header-Boards für 103R und 103V sowie Trägerplatine dafür]&lt;br /&gt;
* [http://www.mikrocontroller.net/articles/Cortex_M3_OCM3U Cortex M3 Artikel im Wiki]&lt;br /&gt;
* [http://olimex.com/dev/index.html STM32 bei Olimex]&lt;br /&gt;
* [http://de.farnell.com/jsp/displayProduct.jsp?sku=1824325&amp;amp;action=view&amp;amp;CMP=GRHS-1000962 STM32Discovery bei Farnell] Mikrocontroller Board (STM32F100RBT6B) mit onboard USB-Programming Interface für ca. 12,50€&lt;br /&gt;
* [http://www.de.rs-online.com/web/p/products/7458434/ STM32Discovery bei RS-Components] 12,65 € +MwSt.&lt;br /&gt;
* [http://www.segor.de/#Q=STM32 VL DISCOVERY] STM32 Discovery bei Segor&lt;br /&gt;
* [http://www.watterott.com/de/STM32F4Discovery STM32F4DISCOVERY] STM32F4 Cortex M4 Controller mit JTAG-Debugger auf der Platine bei Watterott für 16,66EUR.&lt;br /&gt;
* [http://www.conrad.de/ce/de/product/443910/ STM32F4 Discovery Kit bei Conrad] 17,11 €&lt;br /&gt;
* [http://www.mcu-raisonance.com/~open4-development-platform__microcontrollers__tool~tool__T018:g65gu6ghg2n.html/ Open 4 oder auch genannt Evo-Primer]&lt;br /&gt;
* [http://www.wayengineer.com/index.php?main_page=index&amp;amp;cPath=50_66&amp;amp;page=1&amp;amp;sort=3a WayEngineer]&lt;br /&gt;
* [http://thinkembedded.ch/ST-STMicroelectronics:::24.html Im Thinkembedded Shop] in der Schweiz / DiscoveryF4, div. ETT und Olimex Boarde ab 20,18 CHF / 16,15 EUR (inkl. MwSt.) zzgl. Versandkosten&lt;br /&gt;
* [http://shop.myavr.de/ARM-Produktlinie/STM32F4-Discovery.htm?sp=article.sp.php&amp;amp;artID=200072 Im myAVR Shop] DiscoveryF4 mit möglichem Zubehör 16,45 EUR (inkl. MwSt.) zzgl. Versandkosten&lt;br /&gt;
* [http://www.keil.com/boards/cortexm.asp Keil/ARM Demoboards]&lt;br /&gt;
* [http://www.phytec.de Phytec]&lt;br /&gt;
* [http://shop.myavr.de/index.php?sp=artlist_kat.sp.php&amp;amp;katID=37 verschiedene ARM Produkte und Erweiterungen bei myAVR]&lt;br /&gt;
* [http://re.reworld.eu/de/produkte/s64dil-405/index.htm S64DIL-405 STM32Fxxx ARM Cortex M3 Mikrocontrollermodul mit USB-Schnittstelle, Steckbretttauglich] (Leerplatine eignet sich auch für STM32F1xx Prozessoren.)&lt;br /&gt;
&lt;br /&gt;
== Weblinks, Foren, Communities, Tutorials ==&lt;br /&gt;
* [http://www.mikrocontroller.net/articles/STM32_-_Einstieg_mit_Em::Blocks STM32 - Einstieg mit Em::Blocks Tutorial]&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/173753 Diskussion zum Artikel]&lt;br /&gt;
* [http://www.mikrocontroller.net/forum/mikrocontroller-elektronik?filter=ARM*+STM32*+Cortex* Suche im Forum]&lt;br /&gt;
* [[STM32 für Einsteiger]]&lt;br /&gt;
* [[STM32 CooCox Installation]]&lt;br /&gt;
* [https://my.st.com/public/STe2ecommunities/mcu/Lists/ARM%20CortexM3%20STM32/AllItems.aspx Forum auf der ST Homepage] &lt;br /&gt;
* [http://www.stm32circle.com/hom/index.php STM32 Community] &lt;br /&gt;
*[http://joe-c.de/pages/posts/einstieg_mikrocontroller_stm32f103_101.php Einstieg:  STM32board mit Kamera (deutsch)] &lt;br /&gt;
* [http://www.ebv.com/fileadmin/products/Press_Print/Brochures/Product_Brochures/EBV_Cortex%20Collection_V2.pdf Übersicht der Cortex Prozessoren und deren Hersteller (nicht nur ST, von EBV)]&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/258652 Tutorial]&lt;br /&gt;
* [http://diller-technologies.de/stm32_wide.html STM32 Tutorial in Deutsch von Diller Technologies]&lt;br /&gt;
* [http://mySTM32.de STM32 C und C++ Tutorial in Deutsch ]&lt;br /&gt;
* [http://mikrocontroller.bplaced.net STM32F4 Quellcode-Librarys und CooCox-Projekte in Deutsch ]&lt;br /&gt;
* [http://myugl.de Tutorial für Grafik-Librarys und SiSy-Projekte in Deutsch ]&lt;br /&gt;
* [http://www.st.com/web/en/catalog/tools/FM147/CL1794/SC961/SS1533/PF251717 MicroXplorer MCU graphical configuration tool ]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;br /&gt;
[[Kategorie:ARM]]&lt;br /&gt;
[[Kategorie:STM32]]&lt;br /&gt;
[[Kategorie:Mikrocontroller]]&lt;/div&gt;</summary>
		<author><name>Avrprogger</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=STM32_-_Einstieg_mit_Em::Blocks&amp;diff=81861</id>
		<title>STM32 - Einstieg mit Em::Blocks</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=STM32_-_Einstieg_mit_Em::Blocks&amp;diff=81861"/>
		<updated>2014-02-28T15:41:54Z</updated>

		<summary type="html">&lt;p&gt;Avrprogger: /* Core-Coupled-RAM verwenden */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In diesem Tutorial werde ich versuchen, möglichst einfach, die ersten Schritte zur Entwicklung von STM32 Anwenungen mit der Em::Blocks IDE zu erklären. Hier soll nicht so stark auf die einzelnen Peripherie-Module der Controller eingegangen werden, sondern mehr auf die IDE und die verschieden Libraries, wie die CMSIS Library, die DSP-Library, die Standard-Peripheral-Library, die USB-Library und vllt. über Ethernet. Ich denke ein Kapitel zu FreeRTOS wird es auch geben. Auserdem steht im Vordergrund Sachen wie z.B. booten aus dem SRAM, In-Application-Programming, FPU, Core-Coupled-RAM usw. Mal sehn wie weit ich komme ;)&lt;br /&gt;
&lt;br /&gt;
==Die Entwicklungsumgebung==&lt;br /&gt;
===Hardware===&lt;br /&gt;
Zum testen der Anwendungen, benutze ich das STM32F4-Discovery Board, welches einen Debugger, Peripherie und natürlich einen STM32 Controller (STM32F407VGT6) enthält. Deshalb sind alle Beispiele hier für den STM32F407VG Controller ausgelegt, können aber meisten 1:1 auf andere Controller portiert werden. Ich werde auch möglichsts keine STM32F4-Discovery Board spezifischen Libraries verwenden, damit der Portierungs-Vorgang möglichsts einfach bleibt.&lt;br /&gt;
&lt;br /&gt;
===Software===&lt;br /&gt;
In diesem Tutorial verwende ich [http://www.emblocks.org/ Em::Blocks] als IDE. Em::Blocks ist eine kostenlose, uneingeschränkte IDE, die alle STM32 Mikrcontroller unterstützt und sehr einfach zu bedienen ist.&lt;br /&gt;
nach dem Download kann die IDE per Dialog, sehr einfach, installiert werden. Als Compiler beinhaltet Em::Blocks den &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
Die IDE unterstützt zurzeit den ST-Link, den J-Link und es gibt eine Generic-Vorlage, durch welche andere Debugger konfiguriert werden können.&lt;br /&gt;
&lt;br /&gt;
Außerdem muss noch der passende Treiber für den Debugger installiert werden. Verwendet man ein Discovery-Board muss der [http://www.st.com/web/catalog/tools/FM146/CL1984/SC724/SS1677/PF251168 ST-Link/V2]-Treiber heruntergeladen und installiert werden. (Die Installation muss evtl. als Administrator ausgeführt werden, da sonst die Installation unvollständig wird.) Nach der Installation des Treibers kann man den Debugger über die entsprechende USB Schnittstelle an den PC anschließen und es sollte die Meldung von Windows kommen, dass der richtige Treiber gefunden wurde.&lt;br /&gt;
&lt;br /&gt;
===Libraries===&lt;br /&gt;
Zum programmieren benötigt man noch die [http://www.arm.com/products/processors/cortex-m/cortex-microcontroller-software-interface-standard.php CMSIS] und die Standard-Peripheral-Library (z.B. für die F4 Controller [http://www.st.com/stonline/stappl/productcatalog/app?page=partNumberSearchPage&amp;amp;levelid=SS1577&amp;amp;parentid=1743&amp;amp;resourcetype=SW Standard-Peripheral-Library-F4]), die man am besten in einen Ordner (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\STM32&#039;&#039;&#039;&#039;&#039;) entpackt&lt;br /&gt;
&lt;br /&gt;
==Basis-Wissen zur IDE==&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von Dateien zum Projekt===&lt;br /&gt;
Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf &amp;lt;ProjektName&amp;gt; -&amp;gt; Add files...&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Enfernen von Dateien aus dem Projekt===&lt;br /&gt;
Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf die Datei / mehrere Dateien auswählen -&amp;gt; Remove file from project&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
Die Dateien werden lediglich aus dem Projekt entfernt und nicht von der Festplatte gelöscht.&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von Include-Pfaden===&lt;br /&gt;
Sofern die Include-Datei(en) nicht im standard Include-Ordner &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; des Projektes liegen, muss man den Pfad zum Projekt hinzufügen, damit der Compiler die Include-Dateien später auch finden kann. Man geht wie folgt vor: Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; Search Directories -&amp;gt; Add&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von globalen Defines zum Build===&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; #defines&#039;&#039;&#039;&#039;&#039; können globale Defines hinzugefügt werden.&lt;br /&gt;
&lt;br /&gt;
===Compilieren===&lt;br /&gt;
Entweder über das &#039;&#039;&#039;&#039;&#039;Build&#039;&#039;&#039;&#039;&#039; Menü oder über &#039;&#039;&#039;&#039;&#039;F7&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Um eine genau Ausgabe des Compiler-Aufrufes mit allen Argumenten zu bekommen, geht man im &#039;&#039;&#039;&#039;&#039;Settings&#039;&#039;&#039;&#039;&#039; Menü auf &#039;&#039;&#039;&#039;&#039;Tools...&#039;&#039;&#039;&#039;&#039; und dann auf &#039;&#039;&#039;&#039;&#039;Toolchain executables&#039;&#039;&#039;&#039;&#039;. Ganz unten, unter &#039;&#039;&#039;&#039;&#039;Logging&#039;&#039;&#039;&#039;&#039; kann man dann &#039;&#039;&#039;&#039;&#039;Full command line&#039;&#039;&#039;&#039;&#039; auswählen.&lt;br /&gt;
&lt;br /&gt;
====Compiler Optionen====&lt;br /&gt;
=====Optimierung=====&lt;br /&gt;
Standardmäßig verwendet Em::Blocks keine Optimierung. Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; Categories: Optimization&#039;&#039;&#039;&#039;&#039; kann zwischen verschieden Optimierungen ausgewählt werden.&lt;br /&gt;
&lt;br /&gt;
=====Verschiedene C-Standards=====&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; Categories: Language standard&#039;&#039;&#039;&#039;&#039; kann man zwischen verschieden C-Standard auswählen, wie z.B, C99.&lt;br /&gt;
(Mit C99 können auch die Lauf-Variable in der for-Schleife deklariert werden: for(int i;..))&lt;br /&gt;
&lt;br /&gt;
===Debuggen===&lt;br /&gt;
*Als erstes den Debugger starten über das &#039;&#039;&#039;&#039;&#039;Debug&#039;&#039;&#039;&#039;&#039; Menü und &#039;&#039;&#039;&#039;&#039;Start/stop Debug Session&#039;&#039;&#039;&#039;&#039; oder über &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
*Danach läuft die Anwendung auf dem Controller und warten im &#039;&#039;&#039;&#039;&#039;Reset_Handler&#039;&#039;&#039;&#039;&#039; auf Einzelschritt- bzw. Run- Befehle (&#039;&#039;&#039;&#039;&#039;F5, F10, F11&#039;&#039;&#039;&#039;&#039; usw..(siehe &#039;&#039;&#039;&#039;&#039;Debug-Menü&#039;&#039;&#039;&#039;&#039; für alle Möglichkeiten))&lt;br /&gt;
&lt;br /&gt;
*Mit &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039; wird die Debug-Session auch wieder beendet&lt;br /&gt;
&lt;br /&gt;
*Unter &#039;&#039;&#039;&#039;&#039;Debug -&amp;gt; Interfaces -&amp;gt; Target settings&#039;&#039;&#039;&#039;&#039; können Eigenschaften, wie z.B &#039;&#039;&#039;&#039;&#039;Run to main()&#039;&#039;&#039;&#039;&#039; aktiviert werden.&lt;br /&gt;
&lt;br /&gt;
===Projekt als Template abspeichern===&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;File -&amp;gt; Save project as template...&#039;&#039;&#039;&#039;&#039;. Das Template erscheint dann im Projekt-Dialog unter &#039;&#039;&#039;&#039;&#039;User templates&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Das erste Projekt erstellen==&lt;br /&gt;
Hier erkläre ich, wie man am Besten (aus meiner Sicht), ein neues Projekt von Grund auf erstellt, sodass man hinterher, den Controller-Kern über die CMSIS-Library und die Peripherie über die Register steuern kann.&lt;br /&gt;
&lt;br /&gt;
===1. Projekt mit der IDE erstellen===&lt;br /&gt;
Nach der Installation der oben beschriebenen Komponenten erstellt man am besten ein Verzeichnis (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\EmBlocks&#039;&#039;&#039;&#039;&#039;), indem später alle Projekte gespeichert werden. Für Libraries kann man auch noch ein Verzeichnis (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\STM32&#039;&#039;&#039;&#039;&#039;) erstellen, wo alle Libraries gespeichert werden, die man für die Projekt brauchen.&lt;br /&gt;
&lt;br /&gt;
Als nächstes starten man EmBlocks. Bei dem ersten Start öffnet sich ein Fenster, wo verschiedene Compiler angezeigt werden, die Em::Blocks findet. Dort wählt man den &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039; aus und klickt &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039;. Nun sollte sich das Hauptfenster von Em::Blocks öffnen. Über &#039;&#039;&#039;&#039;&#039;Create a new Project&#039;&#039;&#039;&#039;&#039; oder &#039;&#039;&#039;&#039;&#039;File -&amp;gt; New -&amp;gt; Project&#039;&#039;&#039;&#039;&#039; ruft man den Projekt-Dialog auf und kann ein neues Projekt erzeugen.&lt;br /&gt;
&lt;br /&gt;
Auf der Ersten Seite wählen man den &#039;&#039;&#039;&#039;&#039;STmicro-ARM&#039;&#039;&#039;&#039;&#039; Projekt-Typ aus.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_1.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auf der nächsten Seite wird man darauf hingewiesen, dass das der entsprechende Projekt-Typ-Dialog ausgeführt wird. Hier kann man ein Häkchen bei &#039;&#039;&#039;&#039;&#039;Skip this page next time&#039;&#039;&#039;&#039;&#039; setzen und auf &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; klicken.&lt;br /&gt;
&lt;br /&gt;
Im nächsten Schritt wählen man das zuvor erstellt Verzeichnis unter &#039;&#039;&#039;&#039;&#039;Folder to create Project in&#039;&#039;&#039;&#039;&#039; aus, indem später alle Projekt gespeichert werden. Außerdem geben wir dem Projekt einen Namen (z.B. &#039;&#039;&#039;&#039;&#039;FirstProject&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_2.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danach muss man einen Compiler auswählen und bestimmen, welche Projekt-Konfigurationen erszeugt werden sollen. Unter &#039;&#039;&#039;&#039;&#039;Compiler&#039;&#039;&#039;&#039;&#039; wählt man &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039; und man kann das Häkchen bei &#039;&#039;&#039;&#039;&#039;Create &amp;quot;Release&amp;quot; configuration&#039;&#039;&#039;&#039;&#039; entfernen, da diese unnötig ist, die Debug-Konfiguration sollte eig. immer ausreichen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_3.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auf den folgenden Seite wird der Controller ausgewählt. Verwendet man ein STM32F4-Discovery Board müssen folgende Dinge gewählt werden: &#039;&#039;&#039;&#039;&#039;Cortex_M4 (F3xx - F4xx) -&amp;gt; STM32F4xx (Cortex M4 with FPU) -&amp;gt; STM32F407VG&#039;&#039;&#039;&#039;&#039;. Leider sind die Auswahl Möglichkeiten nicht ganz richtig, da auch die F3 Controller einen Cortex M4 Kern und eine FPU haben (Ist aber nicht so wichtig, ist nur eine formale Sache). Außerdem entfernt man das Häkchen bei &#039;&#039;&#039;&#039;&#039;Standard Peripherals Library&#039;&#039;&#039;&#039;&#039; (Wie man die Standard-Peripheral-Library einbindet und verwendet erkläre ich später). Man kann auch das Häkchen bei &#039;&#039;&#039;&#039;&#039;Create hex file for Realease target&#039;&#039;&#039;&#039;&#039; entfernen.&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;Stack Size&#039;&#039;&#039;&#039;&#039; und &#039;&#039;&#039;&#039;&#039;Heap Size&#039;&#039;&#039;&#039;&#039; wird die Größe von Stack und Heap festgelegt. Für eine erste Anwendung kann man die Einstellungen so lassen (Stack-Size: 0x0100 =&amp;gt; 256 Byte Stack und Heap-Size: 0x0000 =&amp;gt; kein Heap). Mit &#039;&#039;&#039;&#039;&#039;Finish&#039;&#039;&#039;&#039;&#039; ist der Projekt Dialog abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_4.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danach sollten sich zwei neue Fenster öffnen, um die Debug-Eigenschaften fest zu legen.&lt;br /&gt;
Verwendet man ein Discovery Board/ST-Link müssen die Einstellungen wie auf dem Bild gewählt werden. Über den Button &#039;&#039;&#039;&#039;&#039;Settings&#039;&#039;&#039;&#039;&#039; öffnet sich das zweite Fenster, falls sich dieses nicht schon von alleine öffnen sollte. Nach den Schließen der Fenster über &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; ist der Projekt Dialog beendet und ein neues Projekt steht zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_5_1.png|Debug Eigenschaften 1. Fenster]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_5_2.png|Debug Eigenschaften 2. Fenster]]&lt;br /&gt;
&lt;br /&gt;
===2. CMSIS-Library und Startup-Code hinzufügen===&lt;br /&gt;
Wenn man sich, nachdem man ein neues Projekt in der IDE erstellt hat, die bereits vorhandenen Dateien im Projekt ansieht, stellt man fest, das bereits ein Ordner &#039;&#039;&#039;&#039;&#039;cmsis&#039;&#039;&#039;&#039;&#039; existiert, der einige wichtige Include-Dateien der CMSIS-Library enthält. Allerdings sind das wirklich nur die wichtigsten Include-Dateien der CMSIS-Library und dazu noch, die aus einer älternen Version. Ich ziehe es deshalb vor die &amp;quot;Mini-CMSIS-Libraray&amp;quot; und die &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c/.h&#039;&#039;&#039;&#039;&#039; Dateien des Projektes durch aktuellere Versionen zu ersetzen. So ist später auch die Integration  von anderen Libraries, wie z.B. der CMSIS-DSP-Libarary einfacher.  &lt;br /&gt;
&lt;br /&gt;
Zunächst gehen man in das Projekt-Verzeichnis und löscht:&lt;br /&gt;
*Den Ordner &#039;&#039;&#039;&#039;&#039;cmsis&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Alle Dateien im Include Verzeichnis &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; im &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner&lt;br /&gt;
&lt;br /&gt;
Außerdem entfernt man auch alle gelöschten Dateien in der IDE aus dem Projekt mit &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Rechts Klick -&amp;gt; Remove file from project&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Es sollte folgende Verzeichnis Struktur überbleiben:&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_6.png|Überbleibende Dateien]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Jetzt müssen die gelöschten Dateien durch die aktuelleren ersetzt werden.&lt;br /&gt;
&lt;br /&gt;
*Dazu kopieren man den gesamten Ordner &#039;&#039;&#039;&#039;&#039;CMSIS&#039;&#039;&#039;&#039;&#039; aus dem CMSIS Download in das Projekt Verzeichnis.&lt;br /&gt;
&lt;br /&gt;
*Aus dem Standard-Peripheral-Library Download kopiert man von &#039;&#039;&#039;&#039;&#039;Libraries\CMSIS\Device\ST\STM32F4xx\Include&#039;&#039;&#039;&#039;&#039; alle Dateien in den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projekt Verzeichnisses&lt;br /&gt;
&lt;br /&gt;
*Aus der Standard-Peripheral-Library kopieren man ebenfalls von &#039;&#039;&#039;&#039;&#039;Libraries\CMSIS\Device\ST\STM32F4xx\Source\Templates&#039;&#039;&#039;&#039;&#039; die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; in den &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner des Projekts&lt;br /&gt;
&lt;br /&gt;
Anschließend müssen die neuen Dateien in der IDE dem Projekt hinzugefügt werden. Dazu benutzt man &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Rechts Klick -&amp;gt; Add files&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
*Aus dem &#039;&#039;&#039;&#039;&#039;CMSIS&#039;&#039;&#039;&#039;&#039; Ordner im Projekt Verzeichnis werden aus den Unterorder &#039;&#039;&#039;&#039;&#039;Include&#039;&#039;&#039;&#039;&#039; folgende Dateien dem Projekt hinzugefügt:&lt;br /&gt;
**arm_common_tables.h&lt;br /&gt;
**arm_const_structs.h&lt;br /&gt;
**arm_math.h&lt;br /&gt;
**core_cm4.h&lt;br /&gt;
**core_cm4_simd.h&lt;br /&gt;
**core_cmFunc.h&lt;br /&gt;
**core_cmInstr.h&lt;br /&gt;
*Alle Dateien aus den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projektes&lt;br /&gt;
*Die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; aus dem &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner&lt;br /&gt;
&lt;br /&gt;
So sollte die Struktur dann aussehen:&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_7.png|Anwenungs-Grundgerüst]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Da einige Dateien der Libraries später bearbeitet werden müssen und Schreibgeschützt sind, weise ich hier schonmal darauf hin, das der Schreibschutz in der IDE über &#039;&#039;&#039;&#039;&#039;Rechts Klick auf die Datei -&amp;gt; Properties -&amp;gt; Häkchen bei &amp;quot;File is read only&amp;quot; entfernen&#039;&#039;&#039;&#039;&#039; entfert werden kann.&lt;br /&gt;
&lt;br /&gt;
Damit die IDE die Header-Dateien der CMSIS Library auch finden kann, weil diese ja nicht im standard Include Ordner &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; liegen, muss unter &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Build Options -&amp;gt; Search Directories&#039;&#039;&#039;&#039;&#039; der Pfad &#039;&#039;&#039;&#039;&#039;CMSIS\Include&#039;&#039;&#039;&#039;&#039; hinzugefügt werden.&lt;br /&gt;
&lt;br /&gt;
Compiliert man jetzt das Projekt mit &#039;&#039;&#039;&#039;&#039;F7&#039;&#039;&#039;&#039;&#039; gibt es ein paar Fehler Meldungen, weil keine Controller-Reihe ausgewählt wurde. Ebenfalls unter &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Build Options -&amp;gt; Compiler Settings -&amp;gt; #defines&#039;&#039;&#039;&#039;&#039; wird der Define &#039;&#039;&#039;&#039;&#039;STM32F40_41xxx&#039;&#039;&#039;&#039;&#039; hinzugefügt.&lt;br /&gt;
&lt;br /&gt;
Beim erneuten Compilieren sollten sich nun keine neuen Fehler ergeben.&lt;br /&gt;
&lt;br /&gt;
===3. Das erste Programm===&lt;br /&gt;
Nachdem ein grundsätzliches &amp;quot;Gerüst&amp;quot; fertig ist, kann man den ersten Code schreiben.&lt;br /&gt;
main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC-&amp;gt;AHB1ENR |= RCC_AHB1ENR_GPIODEN;    //Takt für GPIO aktivieren&lt;br /&gt;
    GPIOD-&amp;gt;MODER |= GPIO_MODER_MODER15_0;   //GPIOD Pin15 als Ausgang&lt;br /&gt;
    GPIOD-&amp;gt;BSRRL |= GPIO_BSRR_BS_15;        //GPIOD Pin15 auf High ziehen&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039; wird dann der Debugger gestartet. Hat der Debugger das Projekt erfolgreich übertragen kann die Ausführung mit &#039;&#039;&#039;&#039;&#039;F5&#039;&#039;&#039;&#039;&#039; begonnen werden.&lt;br /&gt;
&lt;br /&gt;
==Libraries einbinden/verwenden==&lt;br /&gt;
Um Libraries, wie hier im Tutorial, einzubinden, wird ein existierendes Projekt, wie ein im Kapitel [http://www.mikrocontroller.net/articles/STM32_-_Einstieg_mit_Em::Blocks#Das_erste_Projekt_erstellen Das Erste Projekt erstellen] beschrieben wird, vorausgesetzt.&lt;br /&gt;
&lt;br /&gt;
===Einbinden der Standard-Peripheral-Library===&lt;br /&gt;
Um nicht immer die einzelnen Register, wie im ersten &amp;quot;bare-metal&amp;quot; Beispiel, aus dem Reference-Manual zu suchen und zu beschreiben, gibt es von ST die Standard Peripheral Library, die diese Aufgaben übernimmt und mit der sich die &amp;quot;normale/grundlegende&amp;quot; (Alles außer USB und Ethernet) Peripherie recht einfach steuern lässt. Ich kopiere die Standard-Peripheral-Library immer per Hand in das Projekt. Darduch hat man auch gleich die aktuellste Version (in den älteren Version gibt es einige Bugs). &lt;br /&gt;
&lt;br /&gt;
*1. Den Ordner &#039;&#039;&#039;&#039;&#039;Libraries\STM32F4xx_StdPeriph_Driver&#039;&#039;&#039;&#039;&#039; aus dem Standard-Peripheral-Library Download in das Projekt-Verzeichnis kopieren&lt;br /&gt;
*2. Die Datei &#039;&#039;&#039;&#039;&#039;Project\STM32F4xx_StdPeriph_Templates\stm32f4xx_conf.h&#039;&#039;&#039;&#039;&#039; ebenfalls aus dem Standard-Peripheral-Library Download in den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projektes kopieren.&lt;br /&gt;
*3. In der IDE den Include-Path &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\inc&#039;&#039;&#039;&#039;&#039; hinzufügen&lt;br /&gt;
*4. Und das/den Define &#039;&#039;&#039;&#039;&#039;USE_STDPERIPH_DRIVER&#039;&#039;&#039;&#039;&#039; hinzufügen&lt;br /&gt;
*4. Source- und Include-Dateien zum Projekt hinzufügen&lt;br /&gt;
**Achtung: Es dürfen nur die Dateien hinzugefügt werden, für die der Controller auch die entsprechende Peripherie bereit stellt. Diese Dateien dürfen nicht beim STM32F4-Discovery/STM32F407VG hinzugefügt werden.&lt;br /&gt;
***stm32f4xx_dma2d.c/.h&lt;br /&gt;
***stm32f4xx_fmc.c/.h&lt;br /&gt;
***stm32f4xx_ltdc.c/.h&lt;br /&gt;
***stm32f4xx_sai.c/.h&lt;br /&gt;
&lt;br /&gt;
Daraus resultiert folgende Struktur:&lt;br /&gt;
&lt;br /&gt;
[[Datei:stdperiphlib_2.png|Header-Struktur]] [[Datei:stdperiphlib_1.png|Source-Struktur]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Anschließen kann die Standard-Peripheral-Library benutz werden.&lt;br /&gt;
main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);&lt;br /&gt;
&lt;br /&gt;
    GPIO_InitTypeDef GPIOD_InitStructure;&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Mode = GPIO_Mode_OUT;     //Als Ausgang&lt;br /&gt;
    GPIOD_InitStructure.GPIO_OType = GPIO_OType_PP;    //Push-Pull Betrieb&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Pin = GPIO_Pin_15;        //Pin 15 (STM32F4-Discovery: Blaue LED)&lt;br /&gt;
    GPIOD_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;  //Kein Pull-Up oder Pull-Down Widerstand aktiviert&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Speed = GPIO_Speed_25MHz; //25MHz Update-Rate&lt;br /&gt;
    GPIO_Init(GPIOD, &amp;amp;GPIOD_InitStructure);&lt;br /&gt;
&lt;br /&gt;
    GPIO_SetBits(GPIOD, GPIO_Pin_15);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hier ist noch ein &amp;quot;BasicFramework&amp;quot;, dass die komplette CMSIS- und Standard-Peripheral-Library enthält und kann Quasi als Basis für alle Projekte verwendet werden. Allerdings ist das Framework primär auf die STM32F405/7 und STM32F415/7 ausgelegt. Die neueren STM32F401, STM32F42X und STM32F43X  haben noch etwas andere Peripherie, dass Framework müsste dann entsprechend angepasst werden. Download: [[Datei:StdPeriphDriver_BasicFramework.zip]]&lt;br /&gt;
&lt;br /&gt;
===Einbinden der DSP-Library===&lt;br /&gt;
STM32F3 / STM32F4 Microcontroller haben neben der FPU noch einen Digital-Signal-Processor (DSP). Die DSP dient hauptsächlich dazu, viele Daten schnell zu verarbeiten (z.B. Video- oder Audiosignal). Der CMSIS-Download beinhaltet dazu neben der eigentlichen CMSIS-Library auch noch eine DSP-Library. Diese Library stellt sowohl einfache, mathematische Funktionen wie addieren, multiplizieren usw. als auch komplexe Funktionen, wie z.B  einen IIR-Filter, zur Verfügung. Die DSP-Library ist weiter aufgeteilt in kleinere Module, wie z.B. BasicMathFunctions, FilteringFunctions usw. (siehe &#039;&#039;&#039;&#039;&#039;CMSIS\DSP-Library\Source&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
*1. Source-Dateien des benötigten Moduls zum Projekt hinzufügen. (&#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Add files...&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
*2. &#039;&#039;&#039;&#039;&#039;arm_math.h&#039;&#039;&#039;&#039;&#039; in der &#039;&#039;&#039;&#039;&#039;main.c&#039;&#039;&#039;&#039;&#039; einbinden&lt;br /&gt;
*3. Damit die Warnung &amp;quot;Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)&amp;quot; verschwindet, muss der Define &#039;&#039;&#039;&#039;&#039;__FPU_PRESENT&#039;&#039;&#039;&#039;&#039; hinzugefügt werden. (Keine Ahnung, wieso es die Warnung gibt)&lt;br /&gt;
 &lt;br /&gt;
Jetzt kann die DSP-Library verwedet werden. Das Beispiel multipliziert zwei Buffer miteinander. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
#include &amp;quot;arm_math.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    float32_t x[1024];&lt;br /&gt;
    float32_t y[1024];&lt;br /&gt;
    float32_t z[1024];&lt;br /&gt;
&lt;br /&gt;
    for(uint16_t i = 0; i &amp;lt; 1024; i++)&lt;br /&gt;
    {&lt;br /&gt;
        x[i] = i;&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for(uint16_t i = 0; i &amp;lt; 1024; i++)&lt;br /&gt;
    {&lt;br /&gt;
        y[i] = PI;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    arm_mult_f32(x, y, z, 1024);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Startup-Code, Linker-Script, Takt, FPU usw.==&lt;br /&gt;
===Startup-Code===&lt;br /&gt;
Em::Blocks fügt standardmäßig einen Startup-Code mit in das Projekt ein. Die wichtigsten Dinge die darin erledigt werden sind folgende:&lt;br /&gt;
&lt;br /&gt;
*Stack und Heap wird angelgt&lt;br /&gt;
*Die Vector-Table wird angelegt&lt;br /&gt;
*Ein Default Reset-Handler wird implementiert, dieser erledigt folgende aufgaben:&lt;br /&gt;
**Kopieren der definierten Daten aus dem Flash in den SRAM&lt;br /&gt;
**&#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; wird aufgerufen, wenn &#039;&#039;&#039;&#039;&#039;__NO_SYSTEM_INIT&#039;&#039;&#039;&#039;&#039; nicht definiert ist&lt;br /&gt;
**Sprung in die &#039;&#039;&#039;&#039;&#039;main()&#039;&#039;&#039;&#039;&#039; Funktion&lt;br /&gt;
*Allen anderen Interrupt-Handler wird eine Default-Funktion &#039;&#039;&#039;&#039;&#039;def_irq_handler&#039;&#039;&#039;&#039;&#039; mit einer &#039;&#039;&#039;&#039;&#039;while(1)&#039;&#039;&#039;&#039;&#039;-Schleife zugewiesen, falls kein anderer Interrupt-Handler existiert.&lt;br /&gt;
&lt;br /&gt;
Normalerweise muss am Startup-Code nichts verändert werden.&lt;br /&gt;
&lt;br /&gt;
===Linker-Script===&lt;br /&gt;
Em::Blocks stellt zwei fertige Linker-Scripts bereit, eins für die Ausführung des Programmes aus dem Flash (&#039;&#039;&#039;&#039;&#039;*_flash.ld&#039;&#039;&#039;&#039;&#039;), das andere für die Ausführung aus dem SRAM (&#039;&#039;&#039;&#039;&#039;*_sram.ld&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Normalerweise muss auch hier nichts geändert werden, es sei den Daten sollen in bestimmten Adressbereichen abgelegt werden (z.B. im Core-Coupled RAM), was ich später noch zum Tutorial hinzufüge.&lt;br /&gt;
&lt;br /&gt;
===Der Takt===&lt;br /&gt;
Jeder Controller oder Prozessor braucht einen Takt, indem er die einzelnen Maschinen-Befehle abarbeiten kann.&lt;br /&gt;
Bei den STM32 Mikrocontrollern kann dieser Takt aus verschiedenen Quellen kommen:&lt;br /&gt;
&lt;br /&gt;
1. High Speed Internal Oszillator (HSI)&lt;br /&gt;
&lt;br /&gt;
2. High Speed External Oszillator (HSE)&lt;br /&gt;
&lt;br /&gt;
3. Low Speed Internal Oszillator (LSI)&lt;br /&gt;
&lt;br /&gt;
4. Low Speed External Oszillator (LSE)&lt;br /&gt;
&lt;br /&gt;
5. Phase-Locked Loop (PLL) (generiert den Takt aus den ersten vier Taktquellen durch Teiler und Faktoren)&lt;br /&gt;
&lt;br /&gt;
Nach einem Reset wird der Controller aus der HSI Taktquelle versorgt (16MHz beim STM32F407VG). Um die voll Performance des Controllers zu erreichen muss die PLL verwendet werden, welche den Takt durch geschickte Teiler und Faktoren vervielfältigt, sodass am Ende der Controller mit der maximalen Taktfrequenz läuft. Die notwendige Initialisierung der PLL findet in der Funktion &#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; statt. Die PLL erzeugt zunächst einen Basistakt:&lt;br /&gt;
&lt;br /&gt;
PLL_VCO = (F_HSE / PLL_M) * PLL_N&lt;br /&gt;
&lt;br /&gt;
Aus diesem Takt wird dann der Takt für den Controller-Kern abgeleitet:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = PLL_VCO / PLL_P&lt;br /&gt;
&lt;br /&gt;
Und der Takt für SDIO / USB / RNG (48MHz):&lt;br /&gt;
&lt;br /&gt;
48MHz = PLL_VCO / PLL_Q&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Durch weiter Teiler werden, die Takte für die einzelnen Busse erzeugt, da diese nicht alle beliebig schnell betrieben werden dürfen.&lt;br /&gt;
&lt;br /&gt;
Genaue Angaben findet man zu dem jeweiligen Clock-System des Controllers im Reference Manual.&lt;br /&gt;
&lt;br /&gt;
Ein Blick in den &amp;quot;Kommentar-Header&amp;quot; verrät, dass von einem externen (HSE) Oszillator von 25MHz ausgegangen wird, der die PLL versorgen soll.&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((25MHz / PLL_M(25)) * PLL_N(336)) / PLL_P(2) = 168MHz&lt;br /&gt;
&lt;br /&gt;
Allerdings stimmt diese Rechnung natürlich nur, wenn wirklich ein 25MHz Quarz am Controller angeschlossen ist. Auf dem STM32F4-Discovery Board befindet sich aber nur ein 8MHz Quarz. Demnach gilt:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((8MHz / PLL_M(25)) * PLL_N(336)) / PLL_P(2) = 53.76MHz&lt;br /&gt;
&lt;br /&gt;
Der Controller läuft also nur mit 53.76MHz, wenn wie ober beschrieben ein Projekt erstellt wird. Allerdings kann dieses Problem durch ändern von den betroffen Defines behoben werden:&lt;br /&gt;
 &lt;br /&gt;
*Dazu geht man in die &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; Datei und passt zur Vollständigkeit erstmal die zum Controller passende Tabelle im &amp;quot;Kommentar-Header&amp;quot; an (Z.57f):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      HSE Frequency(Hz)                      | 8000000&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      PLL_M                                  | 8&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Danach passt man den PPL_M Define (Z.254) an:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/************************* PLL Parameters *************************************/&lt;br /&gt;
/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */&lt;br /&gt;
#define PLL_M      8&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Außerdem muss man den HSE_VALUE Define in der &#039;&#039;&#039;&#039;&#039;inc/stm32f4xx.h&#039;&#039;&#039;&#039;&#039; angepasst werden (Z.122):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#if !defined  (HSE_VALUE)&lt;br /&gt;
  #define HSE_VALUE    ((uint32_t)8000000) /*!&amp;lt; Value of the External oscillator in Hz */&lt;br /&gt;
&lt;br /&gt;
#endif /* HSE_VALUE */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine neue Berechnung zeigt:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((8MHz / PLL_M(8)) * PLL_N(336)) / PLL_P(2) = 168MHz&lt;br /&gt;
&lt;br /&gt;
Jetzt läuft der Controller mit maximaler Geschwindigkeit.&lt;br /&gt;
&lt;br /&gt;
Die Theorie wird durch folgendes Programm verifiziert. Der geviertelte System-Takt SYSCLK wir am Pin PC9 ausgegeben. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);&lt;br /&gt;
&lt;br /&gt;
    GPIO_InitTypeDef GPIOC_InitStructure;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Mode = GPIO_Mode_AF;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_OType = GPIO_OType_PP;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Pin = GPIO_Pin_9;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;&lt;br /&gt;
    GPIO_Init(GPIOC, &amp;amp;GPIOC_InitStructure);&lt;br /&gt;
&lt;br /&gt;
    RCC_MCO2Config(RCC_MCO2Source_SYSCLK, RCC_MCO2Div_4);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Die FPU===&lt;br /&gt;
====Allgemeines====&lt;br /&gt;
STM32F3 und STM32F4 Controller haben eine FPU.&lt;br /&gt;
Damit die FPU richtig verwendet wird, müssen normalerweise zwei Bedingungen erfüllt sein:&lt;br /&gt;
&lt;br /&gt;
1. Der Controller muss die FPU Hardware-seitig aktivieren&lt;br /&gt;
&lt;br /&gt;
2. Damit die FPU auch was zu tuen bekommt, müssen vom Compiler FPU-Instructions erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
Die Em::Blocks IDE verwendet standardmäßig die FPU, wenn eine Vorhanden ist. Hier wird die FPU Hardware-seitig aktiviert (&#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; Z.341):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* FPU settings ------------------------------------------------------------*/&lt;br /&gt;
  #if (__FPU_PRESENT == 1) &amp;amp;&amp;amp; (__FPU_USED == 1)&lt;br /&gt;
    SCB-&amp;gt;CPACR |= ((3UL &amp;lt;&amp;lt; 10*2)|(3UL &amp;lt;&amp;lt; 11*2));  /* set CP10 and CP11 Full Access */&lt;br /&gt;
  #endif&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
__FPU_PRESENT wird in der &#039;&#039;&#039;&#039;&#039;stm32f4xx.h&#039;&#039;&#039;&#039;&#039; definiert.&lt;br /&gt;
__FPU_USED wird von der IDE übernommen (siehe Build-Log): &#039;&#039;&#039;&#039;&#039;-D__FPU_USED&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Außerdem wird der Compiler von der IDE standardmäßig mit dem Argument &#039;&#039;&#039;&#039;&#039;-mfloat-abi=hard&#039;&#039;&#039;&#039;&#039; aufgerufen, wodurch FPU-Instructions erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
====FPU abschalten====&lt;br /&gt;
Um die FPU ab zu schalten (Mir würde jetzt nur Strom sparen als Grund einfallen) geht man wie folgt vor:&lt;br /&gt;
&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; Device -&amp;gt; Policy&#039;&#039;&#039;&#039;&#039; wählt man &#039;&#039;&#039;&#039;&#039;Use target settings&#039;&#039;&#039;&#039;&#039; und über nimmt die Einstellungen, die vorher dort eingetragen waren, allerdings lässt man das Feld &#039;&#039;&#039;&#039;&#039;FP-hardware&#039;&#039;&#039;&#039;&#039; frei.&lt;br /&gt;
&lt;br /&gt;
[[Datei:fpu_1.png|FPU Abschalten Schritt 1]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;Compiler Settings -&amp;gt; Policy&#039;&#039;&#039;&#039;&#039; wählt man dann &#039;&#039;&#039;&#039;&#039;Use target options only&#039;&#039;&#039;&#039;&#039;. Dann kann man unter &#039;&#039;&#039;&#039;&#039;Categories&#039;&#039;&#039;&#039;&#039; die Option &#039;&#039;&#039;&#039;&#039;ARM FPU architecture&#039;&#039;&#039;&#039;&#039; auswählen. Dort stehen dann drei Möglichkeiten für die FPU zur Verfügung:&lt;br /&gt;
&lt;br /&gt;
1. Software-FPU-Library für Gleitkomma-Berechnung verwenden - Keine FPU-Instructions werden generiert (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=soft&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
2. Eine Mischung aus Software- und Hardware-FPU wird verwendet (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=softfp&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
3. Hardware-FPU wird für Gleitkomma-Berechnungen verwendet (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=hard&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
[[Datei:fpu_2.png|FPU Abschalten Schritt 2]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Um die FPU ab zu schalten wählt man natürlich die erste Möglichkeit.&lt;br /&gt;
Bei der 2. und 3. Möglichkeit fügt die IDE auch den Define &#039;&#039;&#039;&#039;&#039;__FPU_USED&#039;&#039;&#039;&#039;&#039; hinzu. Bei Der ersten Möglichkeit nicht. Der Code muss also nicht verändert / auskommentiert werden.&lt;br /&gt;
&lt;br /&gt;
Um die FPU wieder zu aktivieren müssen alle Schritte wieder rückgängig gemacht werden.&lt;br /&gt;
&lt;br /&gt;
Am besten ist es einfach mal alle Möglichkeiten im Einzelschritt durch zu probieren. Dann stellt man schnell fest, ob die FPU aktiviert wir oder nicht. Ein Blick in den erweiterten &#039;&#039;&#039;&#039;&#039;Build-Log&#039;&#039;&#039;&#039;&#039; gibt auch schnell Aufschluss darüber, wie der Compiler aufgerufen wird (siehe Kapitel [http://www.mikrocontroller.net/articles/STM32_-_Einstieg_mit_Em::Blocks#Compilieren Compilieren]).&lt;br /&gt;
&lt;br /&gt;
====Test Programm für die FPU====&lt;br /&gt;
Hier ein kleines Testprogramm, dass misst wie viele Taktzyklen für eine Gleitkomma-Multiplikation gebraucht werden. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define CORE_SysTickEn()    (*((u32*)0xE0001000)) = 0x40000001&lt;br /&gt;
#define CORE_SysTickDis()   (*((u32*)0xE0001000)) = 0x40000000&lt;br /&gt;
#define CORE_GetSysTick()   (*((u32*)0xE0001004))&lt;br /&gt;
&lt;br /&gt;
uint32_t t1, t2, dt;&lt;br /&gt;
float x, y, z;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    x = 53.64f;&lt;br /&gt;
    y = 0.27f;&lt;br /&gt;
&lt;br /&gt;
    CORE_SysTickEn();&lt;br /&gt;
    t1 = CORE_GetSysTick();&lt;br /&gt;
&lt;br /&gt;
    z = x * y;&lt;br /&gt;
&lt;br /&gt;
    t2 = CORE_GetSysTick();&lt;br /&gt;
    CORE_SysTickDis();&lt;br /&gt;
&lt;br /&gt;
    dt = (t2 - t1) - 9; //9 Takt-Zyklen werden für die Messung gebraucht &lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Core-Coupled-RAM verwenden===&lt;br /&gt;
Auf den normale SRAM kann durch den Core und die verschiedenen DMA-Controller zugegriffen werden. Jedoch können Core und DMA nicht gleichzeitig auf den SRAM zugreifen. Deswegen gibt es einen zweiten kleinen RAM, den Core-Coupled-RAM (CCRAM), auf den nur vom Core zugegriffen werden kann und nicht von einem DMA-Controller. Der CCRAM ist über einen anderen Bus an dem Cortex angeschlossen. Daduch wird ermöglicht, dass der Core sinnvoll weiterarbeiten kann, wenn ein DMA-Controller Daten aus den &amp;quot;Haupt&amp;quot;-RAM ließt/schreibt, indem der Core Daten aus dem CCRAM verarbeitet. Um Daten in den CCRAM zu legen, geht man wie folgt vor:&lt;br /&gt;
&lt;br /&gt;
1. Eine neue Section im Linkerscript anlegen:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
Sections:&lt;br /&gt;
{&lt;br /&gt;
  ...&lt;br /&gt;
&lt;br /&gt;
  .ccram :&lt;br /&gt;
  {&lt;br /&gt;
    *(.ccram)&lt;br /&gt;
  } &amp;gt; CCRAM&lt;br /&gt;
&lt;br /&gt;
  ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Um die neue Section zu verwenden benutzt man diesen Define:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#define CCRAM __attribute__((section(&amp;quot;.ccram&amp;quot;)))&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
int CCRAM dataInCCRAM;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Beim Debuggen stellt man fest das die Variable an der Adresse 0x10000000 liegt, der ersten Adresse das CCRAM&#039;s.&lt;br /&gt;
&lt;br /&gt;
==Booten aus dem SRAM==&lt;br /&gt;
STM32 Controller haben die Möglichkeit Code aus dem Flash als auch aus dem SRAM auszuführen. Um eine Anwenung per Debugger in des SRAM zu laden sind nur wenige Schritte erforderlich:&lt;br /&gt;
&lt;br /&gt;
*Um das Linkerscript für den SRAM zu verwenden geht man zu: &#039;&#039;&#039;&#039;&#039;Build options... -&amp;gt; Device&#039;&#039;&#039;&#039;&#039; dort wählt man unter &#039;&#039;&#039;&#039;&#039;Policy&#039;&#039;&#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;Use target settings&#039;&#039;&#039;&#039;&#039; aus und übernimmt die vorherigen Einstellungen, nur unter &#039;&#039;&#039;&#039;&#039;Linker script*&#039;&#039;&#039;&#039;&#039; gibt man &#039;&#039;&#039;&#039;&#039;.\stm32f407vg_sram.ld&#039;&#039;&#039;&#039;&#039; an&lt;br /&gt;
&lt;br /&gt;
*Dann muss man noch unter &#039;&#039;&#039;&#039;&#039;Debug -&amp;gt; Interfaces -&amp;gt; Settings&#039;&#039;&#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;Vector table start&#039;&#039;&#039;&#039;&#039; auf 0x20000000 ändern und &#039;&#039;&#039;&#039;&#039;Execute from RAM&#039;&#039;&#039;&#039;&#039; auswählen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:bootsram_1.png Booten aus dem SRAM]] [[Datei:bootsram_2.png Booten aus dem SRAM]]&lt;br /&gt;
&lt;br /&gt;
Anschließend kann man die Anwendung ganz normal debuggen. Nach einem Reset muss die Anwenung erneut mit dem Debugger gestartet werden.&lt;br /&gt;
&lt;br /&gt;
=Fortsetzung folgt..=&lt;br /&gt;
Kritik, Wünsche usw. sind gerne erwünscht, am besten hier in den Thread posten: [http://www.mikrocontroller.net/topic/323750 Neues STM32 Tutorial]&lt;br /&gt;
&lt;br /&gt;
[[Category:ARM]]&lt;br /&gt;
[[Category:STM32]]&lt;/div&gt;</summary>
		<author><name>Avrprogger</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=STM32_-_Einstieg_mit_Em::Blocks&amp;diff=81860</id>
		<title>STM32 - Einstieg mit Em::Blocks</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=STM32_-_Einstieg_mit_Em::Blocks&amp;diff=81860"/>
		<updated>2014-02-28T15:32:16Z</updated>

		<summary type="html">&lt;p&gt;Avrprogger: /* Core-Coupled-RAM verwenden */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In diesem Tutorial werde ich versuchen, möglichst einfach, die ersten Schritte zur Entwicklung von STM32 Anwenungen mit der Em::Blocks IDE zu erklären. Hier soll nicht so stark auf die einzelnen Peripherie-Module der Controller eingegangen werden, sondern mehr auf die IDE und die verschieden Libraries, wie die CMSIS Library, die DSP-Library, die Standard-Peripheral-Library, die USB-Library und vllt. über Ethernet. Ich denke ein Kapitel zu FreeRTOS wird es auch geben. Auserdem steht im Vordergrund Sachen wie z.B. booten aus dem SRAM, In-Application-Programming, FPU, Core-Coupled-RAM usw. Mal sehn wie weit ich komme ;)&lt;br /&gt;
&lt;br /&gt;
==Die Entwicklungsumgebung==&lt;br /&gt;
===Hardware===&lt;br /&gt;
Zum testen der Anwendungen, benutze ich das STM32F4-Discovery Board, welches einen Debugger, Peripherie und natürlich einen STM32 Controller (STM32F407VGT6) enthält. Deshalb sind alle Beispiele hier für den STM32F407VG Controller ausgelegt, können aber meisten 1:1 auf andere Controller portiert werden. Ich werde auch möglichsts keine STM32F4-Discovery Board spezifischen Libraries verwenden, damit der Portierungs-Vorgang möglichsts einfach bleibt.&lt;br /&gt;
&lt;br /&gt;
===Software===&lt;br /&gt;
In diesem Tutorial verwende ich [http://www.emblocks.org/ Em::Blocks] als IDE. Em::Blocks ist eine kostenlose, uneingeschränkte IDE, die alle STM32 Mikrcontroller unterstützt und sehr einfach zu bedienen ist.&lt;br /&gt;
nach dem Download kann die IDE per Dialog, sehr einfach, installiert werden. Als Compiler beinhaltet Em::Blocks den &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
Die IDE unterstützt zurzeit den ST-Link, den J-Link und es gibt eine Generic-Vorlage, durch welche andere Debugger konfiguriert werden können.&lt;br /&gt;
&lt;br /&gt;
Außerdem muss noch der passende Treiber für den Debugger installiert werden. Verwendet man ein Discovery-Board muss der [http://www.st.com/web/catalog/tools/FM146/CL1984/SC724/SS1677/PF251168 ST-Link/V2]-Treiber heruntergeladen und installiert werden. (Die Installation muss evtl. als Administrator ausgeführt werden, da sonst die Installation unvollständig wird.) Nach der Installation des Treibers kann man den Debugger über die entsprechende USB Schnittstelle an den PC anschließen und es sollte die Meldung von Windows kommen, dass der richtige Treiber gefunden wurde.&lt;br /&gt;
&lt;br /&gt;
===Libraries===&lt;br /&gt;
Zum programmieren benötigt man noch die [http://www.arm.com/products/processors/cortex-m/cortex-microcontroller-software-interface-standard.php CMSIS] und die Standard-Peripheral-Library (z.B. für die F4 Controller [http://www.st.com/stonline/stappl/productcatalog/app?page=partNumberSearchPage&amp;amp;levelid=SS1577&amp;amp;parentid=1743&amp;amp;resourcetype=SW Standard-Peripheral-Library-F4]), die man am besten in einen Ordner (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\STM32&#039;&#039;&#039;&#039;&#039;) entpackt&lt;br /&gt;
&lt;br /&gt;
==Basis-Wissen zur IDE==&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von Dateien zum Projekt===&lt;br /&gt;
Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf &amp;lt;ProjektName&amp;gt; -&amp;gt; Add files...&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Enfernen von Dateien aus dem Projekt===&lt;br /&gt;
Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf die Datei / mehrere Dateien auswählen -&amp;gt; Remove file from project&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
Die Dateien werden lediglich aus dem Projekt entfernt und nicht von der Festplatte gelöscht.&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von Include-Pfaden===&lt;br /&gt;
Sofern die Include-Datei(en) nicht im standard Include-Ordner &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; des Projektes liegen, muss man den Pfad zum Projekt hinzufügen, damit der Compiler die Include-Dateien später auch finden kann. Man geht wie folgt vor: Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; Search Directories -&amp;gt; Add&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von globalen Defines zum Build===&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; #defines&#039;&#039;&#039;&#039;&#039; können globale Defines hinzugefügt werden.&lt;br /&gt;
&lt;br /&gt;
===Compilieren===&lt;br /&gt;
Entweder über das &#039;&#039;&#039;&#039;&#039;Build&#039;&#039;&#039;&#039;&#039; Menü oder über &#039;&#039;&#039;&#039;&#039;F7&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Um eine genau Ausgabe des Compiler-Aufrufes mit allen Argumenten zu bekommen, geht man im &#039;&#039;&#039;&#039;&#039;Settings&#039;&#039;&#039;&#039;&#039; Menü auf &#039;&#039;&#039;&#039;&#039;Tools...&#039;&#039;&#039;&#039;&#039; und dann auf &#039;&#039;&#039;&#039;&#039;Toolchain executables&#039;&#039;&#039;&#039;&#039;. Ganz unten, unter &#039;&#039;&#039;&#039;&#039;Logging&#039;&#039;&#039;&#039;&#039; kann man dann &#039;&#039;&#039;&#039;&#039;Full command line&#039;&#039;&#039;&#039;&#039; auswählen.&lt;br /&gt;
&lt;br /&gt;
====Compiler Optionen====&lt;br /&gt;
=====Optimierung=====&lt;br /&gt;
Standardmäßig verwendet Em::Blocks keine Optimierung. Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; Categories: Optimization&#039;&#039;&#039;&#039;&#039; kann zwischen verschieden Optimierungen ausgewählt werden.&lt;br /&gt;
&lt;br /&gt;
=====Verschiedene C-Standards=====&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; Categories: Language standard&#039;&#039;&#039;&#039;&#039; kann man zwischen verschieden C-Standard auswählen, wie z.B, C99.&lt;br /&gt;
(Mit C99 können auch die Lauf-Variable in der for-Schleife deklariert werden: for(int i;..))&lt;br /&gt;
&lt;br /&gt;
===Debuggen===&lt;br /&gt;
*Als erstes den Debugger starten über das &#039;&#039;&#039;&#039;&#039;Debug&#039;&#039;&#039;&#039;&#039; Menü und &#039;&#039;&#039;&#039;&#039;Start/stop Debug Session&#039;&#039;&#039;&#039;&#039; oder über &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
*Danach läuft die Anwendung auf dem Controller und warten im &#039;&#039;&#039;&#039;&#039;Reset_Handler&#039;&#039;&#039;&#039;&#039; auf Einzelschritt- bzw. Run- Befehle (&#039;&#039;&#039;&#039;&#039;F5, F10, F11&#039;&#039;&#039;&#039;&#039; usw..(siehe &#039;&#039;&#039;&#039;&#039;Debug-Menü&#039;&#039;&#039;&#039;&#039; für alle Möglichkeiten))&lt;br /&gt;
&lt;br /&gt;
*Mit &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039; wird die Debug-Session auch wieder beendet&lt;br /&gt;
&lt;br /&gt;
*Unter &#039;&#039;&#039;&#039;&#039;Debug -&amp;gt; Interfaces -&amp;gt; Target settings&#039;&#039;&#039;&#039;&#039; können Eigenschaften, wie z.B &#039;&#039;&#039;&#039;&#039;Run to main()&#039;&#039;&#039;&#039;&#039; aktiviert werden.&lt;br /&gt;
&lt;br /&gt;
===Projekt als Template abspeichern===&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;File -&amp;gt; Save project as template...&#039;&#039;&#039;&#039;&#039;. Das Template erscheint dann im Projekt-Dialog unter &#039;&#039;&#039;&#039;&#039;User templates&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Das erste Projekt erstellen==&lt;br /&gt;
Hier erkläre ich, wie man am Besten (aus meiner Sicht), ein neues Projekt von Grund auf erstellt, sodass man hinterher, den Controller-Kern über die CMSIS-Library und die Peripherie über die Register steuern kann.&lt;br /&gt;
&lt;br /&gt;
===1. Projekt mit der IDE erstellen===&lt;br /&gt;
Nach der Installation der oben beschriebenen Komponenten erstellt man am besten ein Verzeichnis (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\EmBlocks&#039;&#039;&#039;&#039;&#039;), indem später alle Projekte gespeichert werden. Für Libraries kann man auch noch ein Verzeichnis (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\STM32&#039;&#039;&#039;&#039;&#039;) erstellen, wo alle Libraries gespeichert werden, die man für die Projekt brauchen.&lt;br /&gt;
&lt;br /&gt;
Als nächstes starten man EmBlocks. Bei dem ersten Start öffnet sich ein Fenster, wo verschiedene Compiler angezeigt werden, die Em::Blocks findet. Dort wählt man den &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039; aus und klickt &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039;. Nun sollte sich das Hauptfenster von Em::Blocks öffnen. Über &#039;&#039;&#039;&#039;&#039;Create a new Project&#039;&#039;&#039;&#039;&#039; oder &#039;&#039;&#039;&#039;&#039;File -&amp;gt; New -&amp;gt; Project&#039;&#039;&#039;&#039;&#039; ruft man den Projekt-Dialog auf und kann ein neues Projekt erzeugen.&lt;br /&gt;
&lt;br /&gt;
Auf der Ersten Seite wählen man den &#039;&#039;&#039;&#039;&#039;STmicro-ARM&#039;&#039;&#039;&#039;&#039; Projekt-Typ aus.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_1.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auf der nächsten Seite wird man darauf hingewiesen, dass das der entsprechende Projekt-Typ-Dialog ausgeführt wird. Hier kann man ein Häkchen bei &#039;&#039;&#039;&#039;&#039;Skip this page next time&#039;&#039;&#039;&#039;&#039; setzen und auf &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; klicken.&lt;br /&gt;
&lt;br /&gt;
Im nächsten Schritt wählen man das zuvor erstellt Verzeichnis unter &#039;&#039;&#039;&#039;&#039;Folder to create Project in&#039;&#039;&#039;&#039;&#039; aus, indem später alle Projekt gespeichert werden. Außerdem geben wir dem Projekt einen Namen (z.B. &#039;&#039;&#039;&#039;&#039;FirstProject&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_2.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danach muss man einen Compiler auswählen und bestimmen, welche Projekt-Konfigurationen erszeugt werden sollen. Unter &#039;&#039;&#039;&#039;&#039;Compiler&#039;&#039;&#039;&#039;&#039; wählt man &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039; und man kann das Häkchen bei &#039;&#039;&#039;&#039;&#039;Create &amp;quot;Release&amp;quot; configuration&#039;&#039;&#039;&#039;&#039; entfernen, da diese unnötig ist, die Debug-Konfiguration sollte eig. immer ausreichen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_3.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auf den folgenden Seite wird der Controller ausgewählt. Verwendet man ein STM32F4-Discovery Board müssen folgende Dinge gewählt werden: &#039;&#039;&#039;&#039;&#039;Cortex_M4 (F3xx - F4xx) -&amp;gt; STM32F4xx (Cortex M4 with FPU) -&amp;gt; STM32F407VG&#039;&#039;&#039;&#039;&#039;. Leider sind die Auswahl Möglichkeiten nicht ganz richtig, da auch die F3 Controller einen Cortex M4 Kern und eine FPU haben (Ist aber nicht so wichtig, ist nur eine formale Sache). Außerdem entfernt man das Häkchen bei &#039;&#039;&#039;&#039;&#039;Standard Peripherals Library&#039;&#039;&#039;&#039;&#039; (Wie man die Standard-Peripheral-Library einbindet und verwendet erkläre ich später). Man kann auch das Häkchen bei &#039;&#039;&#039;&#039;&#039;Create hex file for Realease target&#039;&#039;&#039;&#039;&#039; entfernen.&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;Stack Size&#039;&#039;&#039;&#039;&#039; und &#039;&#039;&#039;&#039;&#039;Heap Size&#039;&#039;&#039;&#039;&#039; wird die Größe von Stack und Heap festgelegt. Für eine erste Anwendung kann man die Einstellungen so lassen (Stack-Size: 0x0100 =&amp;gt; 256 Byte Stack und Heap-Size: 0x0000 =&amp;gt; kein Heap). Mit &#039;&#039;&#039;&#039;&#039;Finish&#039;&#039;&#039;&#039;&#039; ist der Projekt Dialog abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_4.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danach sollten sich zwei neue Fenster öffnen, um die Debug-Eigenschaften fest zu legen.&lt;br /&gt;
Verwendet man ein Discovery Board/ST-Link müssen die Einstellungen wie auf dem Bild gewählt werden. Über den Button &#039;&#039;&#039;&#039;&#039;Settings&#039;&#039;&#039;&#039;&#039; öffnet sich das zweite Fenster, falls sich dieses nicht schon von alleine öffnen sollte. Nach den Schließen der Fenster über &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; ist der Projekt Dialog beendet und ein neues Projekt steht zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_5_1.png|Debug Eigenschaften 1. Fenster]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_5_2.png|Debug Eigenschaften 2. Fenster]]&lt;br /&gt;
&lt;br /&gt;
===2. CMSIS-Library und Startup-Code hinzufügen===&lt;br /&gt;
Wenn man sich, nachdem man ein neues Projekt in der IDE erstellt hat, die bereits vorhandenen Dateien im Projekt ansieht, stellt man fest, das bereits ein Ordner &#039;&#039;&#039;&#039;&#039;cmsis&#039;&#039;&#039;&#039;&#039; existiert, der einige wichtige Include-Dateien der CMSIS-Library enthält. Allerdings sind das wirklich nur die wichtigsten Include-Dateien der CMSIS-Library und dazu noch, die aus einer älternen Version. Ich ziehe es deshalb vor die &amp;quot;Mini-CMSIS-Libraray&amp;quot; und die &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c/.h&#039;&#039;&#039;&#039;&#039; Dateien des Projektes durch aktuellere Versionen zu ersetzen. So ist später auch die Integration  von anderen Libraries, wie z.B. der CMSIS-DSP-Libarary einfacher.  &lt;br /&gt;
&lt;br /&gt;
Zunächst gehen man in das Projekt-Verzeichnis und löscht:&lt;br /&gt;
*Den Ordner &#039;&#039;&#039;&#039;&#039;cmsis&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Alle Dateien im Include Verzeichnis &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; im &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner&lt;br /&gt;
&lt;br /&gt;
Außerdem entfernt man auch alle gelöschten Dateien in der IDE aus dem Projekt mit &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Rechts Klick -&amp;gt; Remove file from project&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Es sollte folgende Verzeichnis Struktur überbleiben:&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_6.png|Überbleibende Dateien]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Jetzt müssen die gelöschten Dateien durch die aktuelleren ersetzt werden.&lt;br /&gt;
&lt;br /&gt;
*Dazu kopieren man den gesamten Ordner &#039;&#039;&#039;&#039;&#039;CMSIS&#039;&#039;&#039;&#039;&#039; aus dem CMSIS Download in das Projekt Verzeichnis.&lt;br /&gt;
&lt;br /&gt;
*Aus dem Standard-Peripheral-Library Download kopiert man von &#039;&#039;&#039;&#039;&#039;Libraries\CMSIS\Device\ST\STM32F4xx\Include&#039;&#039;&#039;&#039;&#039; alle Dateien in den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projekt Verzeichnisses&lt;br /&gt;
&lt;br /&gt;
*Aus der Standard-Peripheral-Library kopieren man ebenfalls von &#039;&#039;&#039;&#039;&#039;Libraries\CMSIS\Device\ST\STM32F4xx\Source\Templates&#039;&#039;&#039;&#039;&#039; die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; in den &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner des Projekts&lt;br /&gt;
&lt;br /&gt;
Anschließend müssen die neuen Dateien in der IDE dem Projekt hinzugefügt werden. Dazu benutzt man &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Rechts Klick -&amp;gt; Add files&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
*Aus dem &#039;&#039;&#039;&#039;&#039;CMSIS&#039;&#039;&#039;&#039;&#039; Ordner im Projekt Verzeichnis werden aus den Unterorder &#039;&#039;&#039;&#039;&#039;Include&#039;&#039;&#039;&#039;&#039; folgende Dateien dem Projekt hinzugefügt:&lt;br /&gt;
**arm_common_tables.h&lt;br /&gt;
**arm_const_structs.h&lt;br /&gt;
**arm_math.h&lt;br /&gt;
**core_cm4.h&lt;br /&gt;
**core_cm4_simd.h&lt;br /&gt;
**core_cmFunc.h&lt;br /&gt;
**core_cmInstr.h&lt;br /&gt;
*Alle Dateien aus den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projektes&lt;br /&gt;
*Die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; aus dem &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner&lt;br /&gt;
&lt;br /&gt;
So sollte die Struktur dann aussehen:&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_7.png|Anwenungs-Grundgerüst]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Da einige Dateien der Libraries später bearbeitet werden müssen und Schreibgeschützt sind, weise ich hier schonmal darauf hin, das der Schreibschutz in der IDE über &#039;&#039;&#039;&#039;&#039;Rechts Klick auf die Datei -&amp;gt; Properties -&amp;gt; Häkchen bei &amp;quot;File is read only&amp;quot; entfernen&#039;&#039;&#039;&#039;&#039; entfert werden kann.&lt;br /&gt;
&lt;br /&gt;
Damit die IDE die Header-Dateien der CMSIS Library auch finden kann, weil diese ja nicht im standard Include Ordner &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; liegen, muss unter &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Build Options -&amp;gt; Search Directories&#039;&#039;&#039;&#039;&#039; der Pfad &#039;&#039;&#039;&#039;&#039;CMSIS\Include&#039;&#039;&#039;&#039;&#039; hinzugefügt werden.&lt;br /&gt;
&lt;br /&gt;
Compiliert man jetzt das Projekt mit &#039;&#039;&#039;&#039;&#039;F7&#039;&#039;&#039;&#039;&#039; gibt es ein paar Fehler Meldungen, weil keine Controller-Reihe ausgewählt wurde. Ebenfalls unter &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Build Options -&amp;gt; Compiler Settings -&amp;gt; #defines&#039;&#039;&#039;&#039;&#039; wird der Define &#039;&#039;&#039;&#039;&#039;STM32F40_41xxx&#039;&#039;&#039;&#039;&#039; hinzugefügt.&lt;br /&gt;
&lt;br /&gt;
Beim erneuten Compilieren sollten sich nun keine neuen Fehler ergeben.&lt;br /&gt;
&lt;br /&gt;
===3. Das erste Programm===&lt;br /&gt;
Nachdem ein grundsätzliches &amp;quot;Gerüst&amp;quot; fertig ist, kann man den ersten Code schreiben.&lt;br /&gt;
main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC-&amp;gt;AHB1ENR |= RCC_AHB1ENR_GPIODEN;    //Takt für GPIO aktivieren&lt;br /&gt;
    GPIOD-&amp;gt;MODER |= GPIO_MODER_MODER15_0;   //GPIOD Pin15 als Ausgang&lt;br /&gt;
    GPIOD-&amp;gt;BSRRL |= GPIO_BSRR_BS_15;        //GPIOD Pin15 auf High ziehen&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039; wird dann der Debugger gestartet. Hat der Debugger das Projekt erfolgreich übertragen kann die Ausführung mit &#039;&#039;&#039;&#039;&#039;F5&#039;&#039;&#039;&#039;&#039; begonnen werden.&lt;br /&gt;
&lt;br /&gt;
==Libraries einbinden/verwenden==&lt;br /&gt;
Um Libraries, wie hier im Tutorial, einzubinden, wird ein existierendes Projekt, wie ein im Kapitel [http://www.mikrocontroller.net/articles/STM32_-_Einstieg_mit_Em::Blocks#Das_erste_Projekt_erstellen Das Erste Projekt erstellen] beschrieben wird, vorausgesetzt.&lt;br /&gt;
&lt;br /&gt;
===Einbinden der Standard-Peripheral-Library===&lt;br /&gt;
Um nicht immer die einzelnen Register, wie im ersten &amp;quot;bare-metal&amp;quot; Beispiel, aus dem Reference-Manual zu suchen und zu beschreiben, gibt es von ST die Standard Peripheral Library, die diese Aufgaben übernimmt und mit der sich die &amp;quot;normale/grundlegende&amp;quot; (Alles außer USB und Ethernet) Peripherie recht einfach steuern lässt. Ich kopiere die Standard-Peripheral-Library immer per Hand in das Projekt. Darduch hat man auch gleich die aktuellste Version (in den älteren Version gibt es einige Bugs). &lt;br /&gt;
&lt;br /&gt;
*1. Den Ordner &#039;&#039;&#039;&#039;&#039;Libraries\STM32F4xx_StdPeriph_Driver&#039;&#039;&#039;&#039;&#039; aus dem Standard-Peripheral-Library Download in das Projekt-Verzeichnis kopieren&lt;br /&gt;
*2. Die Datei &#039;&#039;&#039;&#039;&#039;Project\STM32F4xx_StdPeriph_Templates\stm32f4xx_conf.h&#039;&#039;&#039;&#039;&#039; ebenfalls aus dem Standard-Peripheral-Library Download in den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projektes kopieren.&lt;br /&gt;
*3. In der IDE den Include-Path &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\inc&#039;&#039;&#039;&#039;&#039; hinzufügen&lt;br /&gt;
*4. Und das/den Define &#039;&#039;&#039;&#039;&#039;USE_STDPERIPH_DRIVER&#039;&#039;&#039;&#039;&#039; hinzufügen&lt;br /&gt;
*4. Source- und Include-Dateien zum Projekt hinzufügen&lt;br /&gt;
**Achtung: Es dürfen nur die Dateien hinzugefügt werden, für die der Controller auch die entsprechende Peripherie bereit stellt. Diese Dateien dürfen nicht beim STM32F4-Discovery/STM32F407VG hinzugefügt werden.&lt;br /&gt;
***stm32f4xx_dma2d.c/.h&lt;br /&gt;
***stm32f4xx_fmc.c/.h&lt;br /&gt;
***stm32f4xx_ltdc.c/.h&lt;br /&gt;
***stm32f4xx_sai.c/.h&lt;br /&gt;
&lt;br /&gt;
Daraus resultiert folgende Struktur:&lt;br /&gt;
&lt;br /&gt;
[[Datei:stdperiphlib_2.png|Header-Struktur]] [[Datei:stdperiphlib_1.png|Source-Struktur]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Anschließen kann die Standard-Peripheral-Library benutz werden.&lt;br /&gt;
main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);&lt;br /&gt;
&lt;br /&gt;
    GPIO_InitTypeDef GPIOD_InitStructure;&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Mode = GPIO_Mode_OUT;     //Als Ausgang&lt;br /&gt;
    GPIOD_InitStructure.GPIO_OType = GPIO_OType_PP;    //Push-Pull Betrieb&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Pin = GPIO_Pin_15;        //Pin 15 (STM32F4-Discovery: Blaue LED)&lt;br /&gt;
    GPIOD_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;  //Kein Pull-Up oder Pull-Down Widerstand aktiviert&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Speed = GPIO_Speed_25MHz; //25MHz Update-Rate&lt;br /&gt;
    GPIO_Init(GPIOD, &amp;amp;GPIOD_InitStructure);&lt;br /&gt;
&lt;br /&gt;
    GPIO_SetBits(GPIOD, GPIO_Pin_15);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hier ist noch ein &amp;quot;BasicFramework&amp;quot;, dass die komplette CMSIS- und Standard-Peripheral-Library enthält und kann Quasi als Basis für alle Projekte verwendet werden. Allerdings ist das Framework primär auf die STM32F405/7 und STM32F415/7 ausgelegt. Die neueren STM32F401, STM32F42X und STM32F43X  haben noch etwas andere Peripherie, dass Framework müsste dann entsprechend angepasst werden. Download: [[Datei:StdPeriphDriver_BasicFramework.zip]]&lt;br /&gt;
&lt;br /&gt;
===Einbinden der DSP-Library===&lt;br /&gt;
STM32F3 / STM32F4 Microcontroller haben neben der FPU noch einen Digital-Signal-Processor (DSP). Die DSP dient hauptsächlich dazu, viele Daten schnell zu verarbeiten (z.B. Video- oder Audiosignal). Der CMSIS-Download beinhaltet dazu neben der eigentlichen CMSIS-Library auch noch eine DSP-Library. Diese Library stellt sowohl einfache, mathematische Funktionen wie addieren, multiplizieren usw. als auch komplexe Funktionen, wie z.B  einen IIR-Filter, zur Verfügung. Die DSP-Library ist weiter aufgeteilt in kleinere Module, wie z.B. BasicMathFunctions, FilteringFunctions usw. (siehe &#039;&#039;&#039;&#039;&#039;CMSIS\DSP-Library\Source&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
*1. Source-Dateien des benötigten Moduls zum Projekt hinzufügen. (&#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Add files...&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
*2. &#039;&#039;&#039;&#039;&#039;arm_math.h&#039;&#039;&#039;&#039;&#039; in der &#039;&#039;&#039;&#039;&#039;main.c&#039;&#039;&#039;&#039;&#039; einbinden&lt;br /&gt;
*3. Damit die Warnung &amp;quot;Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)&amp;quot; verschwindet, muss der Define &#039;&#039;&#039;&#039;&#039;__FPU_PRESENT&#039;&#039;&#039;&#039;&#039; hinzugefügt werden. (Keine Ahnung, wieso es die Warnung gibt)&lt;br /&gt;
 &lt;br /&gt;
Jetzt kann die DSP-Library verwedet werden. Das Beispiel multipliziert zwei Buffer miteinander. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
#include &amp;quot;arm_math.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    float32_t x[1024];&lt;br /&gt;
    float32_t y[1024];&lt;br /&gt;
    float32_t z[1024];&lt;br /&gt;
&lt;br /&gt;
    for(uint16_t i = 0; i &amp;lt; 1024; i++)&lt;br /&gt;
    {&lt;br /&gt;
        x[i] = i;&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for(uint16_t i = 0; i &amp;lt; 1024; i++)&lt;br /&gt;
    {&lt;br /&gt;
        y[i] = PI;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    arm_mult_f32(x, y, z, 1024);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Startup-Code, Linker-Script, Takt, FPU usw.==&lt;br /&gt;
===Startup-Code===&lt;br /&gt;
Em::Blocks fügt standardmäßig einen Startup-Code mit in das Projekt ein. Die wichtigsten Dinge die darin erledigt werden sind folgende:&lt;br /&gt;
&lt;br /&gt;
*Stack und Heap wird angelgt&lt;br /&gt;
*Die Vector-Table wird angelegt&lt;br /&gt;
*Ein Default Reset-Handler wird implementiert, dieser erledigt folgende aufgaben:&lt;br /&gt;
**Kopieren der definierten Daten aus dem Flash in den SRAM&lt;br /&gt;
**&#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; wird aufgerufen, wenn &#039;&#039;&#039;&#039;&#039;__NO_SYSTEM_INIT&#039;&#039;&#039;&#039;&#039; nicht definiert ist&lt;br /&gt;
**Sprung in die &#039;&#039;&#039;&#039;&#039;main()&#039;&#039;&#039;&#039;&#039; Funktion&lt;br /&gt;
*Allen anderen Interrupt-Handler wird eine Default-Funktion &#039;&#039;&#039;&#039;&#039;def_irq_handler&#039;&#039;&#039;&#039;&#039; mit einer &#039;&#039;&#039;&#039;&#039;while(1)&#039;&#039;&#039;&#039;&#039;-Schleife zugewiesen, falls kein anderer Interrupt-Handler existiert.&lt;br /&gt;
&lt;br /&gt;
Normalerweise muss am Startup-Code nichts verändert werden.&lt;br /&gt;
&lt;br /&gt;
===Linker-Script===&lt;br /&gt;
Em::Blocks stellt zwei fertige Linker-Scripts bereit, eins für die Ausführung des Programmes aus dem Flash (&#039;&#039;&#039;&#039;&#039;*_flash.ld&#039;&#039;&#039;&#039;&#039;), das andere für die Ausführung aus dem SRAM (&#039;&#039;&#039;&#039;&#039;*_sram.ld&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Normalerweise muss auch hier nichts geändert werden, es sei den Daten sollen in bestimmten Adressbereichen abgelegt werden (z.B. im Core-Coupled RAM), was ich später noch zum Tutorial hinzufüge.&lt;br /&gt;
&lt;br /&gt;
===Der Takt===&lt;br /&gt;
Jeder Controller oder Prozessor braucht einen Takt, indem er die einzelnen Maschinen-Befehle abarbeiten kann.&lt;br /&gt;
Bei den STM32 Mikrocontrollern kann dieser Takt aus verschiedenen Quellen kommen:&lt;br /&gt;
&lt;br /&gt;
1. High Speed Internal Oszillator (HSI)&lt;br /&gt;
&lt;br /&gt;
2. High Speed External Oszillator (HSE)&lt;br /&gt;
&lt;br /&gt;
3. Low Speed Internal Oszillator (LSI)&lt;br /&gt;
&lt;br /&gt;
4. Low Speed External Oszillator (LSE)&lt;br /&gt;
&lt;br /&gt;
5. Phase-Locked Loop (PLL) (generiert den Takt aus den ersten vier Taktquellen durch Teiler und Faktoren)&lt;br /&gt;
&lt;br /&gt;
Nach einem Reset wird der Controller aus der HSI Taktquelle versorgt (16MHz beim STM32F407VG). Um die voll Performance des Controllers zu erreichen muss die PLL verwendet werden, welche den Takt durch geschickte Teiler und Faktoren vervielfältigt, sodass am Ende der Controller mit der maximalen Taktfrequenz läuft. Die notwendige Initialisierung der PLL findet in der Funktion &#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; statt. Die PLL erzeugt zunächst einen Basistakt:&lt;br /&gt;
&lt;br /&gt;
PLL_VCO = (F_HSE / PLL_M) * PLL_N&lt;br /&gt;
&lt;br /&gt;
Aus diesem Takt wird dann der Takt für den Controller-Kern abgeleitet:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = PLL_VCO / PLL_P&lt;br /&gt;
&lt;br /&gt;
Und der Takt für SDIO / USB / RNG (48MHz):&lt;br /&gt;
&lt;br /&gt;
48MHz = PLL_VCO / PLL_Q&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Durch weiter Teiler werden, die Takte für die einzelnen Busse erzeugt, da diese nicht alle beliebig schnell betrieben werden dürfen.&lt;br /&gt;
&lt;br /&gt;
Genaue Angaben findet man zu dem jeweiligen Clock-System des Controllers im Reference Manual.&lt;br /&gt;
&lt;br /&gt;
Ein Blick in den &amp;quot;Kommentar-Header&amp;quot; verrät, dass von einem externen (HSE) Oszillator von 25MHz ausgegangen wird, der die PLL versorgen soll.&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((25MHz / PLL_M(25)) * PLL_N(336)) / PLL_P(2) = 168MHz&lt;br /&gt;
&lt;br /&gt;
Allerdings stimmt diese Rechnung natürlich nur, wenn wirklich ein 25MHz Quarz am Controller angeschlossen ist. Auf dem STM32F4-Discovery Board befindet sich aber nur ein 8MHz Quarz. Demnach gilt:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((8MHz / PLL_M(25)) * PLL_N(336)) / PLL_P(2) = 53.76MHz&lt;br /&gt;
&lt;br /&gt;
Der Controller läuft also nur mit 53.76MHz, wenn wie ober beschrieben ein Projekt erstellt wird. Allerdings kann dieses Problem durch ändern von den betroffen Defines behoben werden:&lt;br /&gt;
 &lt;br /&gt;
*Dazu geht man in die &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; Datei und passt zur Vollständigkeit erstmal die zum Controller passende Tabelle im &amp;quot;Kommentar-Header&amp;quot; an (Z.57f):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      HSE Frequency(Hz)                      | 8000000&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      PLL_M                                  | 8&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Danach passt man den PPL_M Define (Z.254) an:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/************************* PLL Parameters *************************************/&lt;br /&gt;
/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */&lt;br /&gt;
#define PLL_M      8&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Außerdem muss man den HSE_VALUE Define in der &#039;&#039;&#039;&#039;&#039;inc/stm32f4xx.h&#039;&#039;&#039;&#039;&#039; angepasst werden (Z.122):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#if !defined  (HSE_VALUE)&lt;br /&gt;
  #define HSE_VALUE    ((uint32_t)8000000) /*!&amp;lt; Value of the External oscillator in Hz */&lt;br /&gt;
&lt;br /&gt;
#endif /* HSE_VALUE */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine neue Berechnung zeigt:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((8MHz / PLL_M(8)) * PLL_N(336)) / PLL_P(2) = 168MHz&lt;br /&gt;
&lt;br /&gt;
Jetzt läuft der Controller mit maximaler Geschwindigkeit.&lt;br /&gt;
&lt;br /&gt;
Die Theorie wird durch folgendes Programm verifiziert. Der geviertelte System-Takt SYSCLK wir am Pin PC9 ausgegeben. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);&lt;br /&gt;
&lt;br /&gt;
    GPIO_InitTypeDef GPIOC_InitStructure;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Mode = GPIO_Mode_AF;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_OType = GPIO_OType_PP;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Pin = GPIO_Pin_9;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;&lt;br /&gt;
    GPIO_Init(GPIOC, &amp;amp;GPIOC_InitStructure);&lt;br /&gt;
&lt;br /&gt;
    RCC_MCO2Config(RCC_MCO2Source_SYSCLK, RCC_MCO2Div_4);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Die FPU===&lt;br /&gt;
====Allgemeines====&lt;br /&gt;
STM32F3 und STM32F4 Controller haben eine FPU.&lt;br /&gt;
Damit die FPU richtig verwendet wird, müssen normalerweise zwei Bedingungen erfüllt sein:&lt;br /&gt;
&lt;br /&gt;
1. Der Controller muss die FPU Hardware-seitig aktivieren&lt;br /&gt;
&lt;br /&gt;
2. Damit die FPU auch was zu tuen bekommt, müssen vom Compiler FPU-Instructions erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
Die Em::Blocks IDE verwendet standardmäßig die FPU, wenn eine Vorhanden ist. Hier wird die FPU Hardware-seitig aktiviert (&#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; Z.341):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* FPU settings ------------------------------------------------------------*/&lt;br /&gt;
  #if (__FPU_PRESENT == 1) &amp;amp;&amp;amp; (__FPU_USED == 1)&lt;br /&gt;
    SCB-&amp;gt;CPACR |= ((3UL &amp;lt;&amp;lt; 10*2)|(3UL &amp;lt;&amp;lt; 11*2));  /* set CP10 and CP11 Full Access */&lt;br /&gt;
  #endif&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
__FPU_PRESENT wird in der &#039;&#039;&#039;&#039;&#039;stm32f4xx.h&#039;&#039;&#039;&#039;&#039; definiert.&lt;br /&gt;
__FPU_USED wird von der IDE übernommen (siehe Build-Log): &#039;&#039;&#039;&#039;&#039;-D__FPU_USED&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Außerdem wird der Compiler von der IDE standardmäßig mit dem Argument &#039;&#039;&#039;&#039;&#039;-mfloat-abi=hard&#039;&#039;&#039;&#039;&#039; aufgerufen, wodurch FPU-Instructions erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
====FPU abschalten====&lt;br /&gt;
Um die FPU ab zu schalten (Mir würde jetzt nur Strom sparen als Grund einfallen) geht man wie folgt vor:&lt;br /&gt;
&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; Device -&amp;gt; Policy&#039;&#039;&#039;&#039;&#039; wählt man &#039;&#039;&#039;&#039;&#039;Use target settings&#039;&#039;&#039;&#039;&#039; und über nimmt die Einstellungen, die vorher dort eingetragen waren, allerdings lässt man das Feld &#039;&#039;&#039;&#039;&#039;FP-hardware&#039;&#039;&#039;&#039;&#039; frei.&lt;br /&gt;
&lt;br /&gt;
[[Datei:fpu_1.png|FPU Abschalten Schritt 1]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;Compiler Settings -&amp;gt; Policy&#039;&#039;&#039;&#039;&#039; wählt man dann &#039;&#039;&#039;&#039;&#039;Use target options only&#039;&#039;&#039;&#039;&#039;. Dann kann man unter &#039;&#039;&#039;&#039;&#039;Categories&#039;&#039;&#039;&#039;&#039; die Option &#039;&#039;&#039;&#039;&#039;ARM FPU architecture&#039;&#039;&#039;&#039;&#039; auswählen. Dort stehen dann drei Möglichkeiten für die FPU zur Verfügung:&lt;br /&gt;
&lt;br /&gt;
1. Software-FPU-Library für Gleitkomma-Berechnung verwenden - Keine FPU-Instructions werden generiert (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=soft&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
2. Eine Mischung aus Software- und Hardware-FPU wird verwendet (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=softfp&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
3. Hardware-FPU wird für Gleitkomma-Berechnungen verwendet (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=hard&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
[[Datei:fpu_2.png|FPU Abschalten Schritt 2]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Um die FPU ab zu schalten wählt man natürlich die erste Möglichkeit.&lt;br /&gt;
Bei der 2. und 3. Möglichkeit fügt die IDE auch den Define &#039;&#039;&#039;&#039;&#039;__FPU_USED&#039;&#039;&#039;&#039;&#039; hinzu. Bei Der ersten Möglichkeit nicht. Der Code muss also nicht verändert / auskommentiert werden.&lt;br /&gt;
&lt;br /&gt;
Um die FPU wieder zu aktivieren müssen alle Schritte wieder rückgängig gemacht werden.&lt;br /&gt;
&lt;br /&gt;
Am besten ist es einfach mal alle Möglichkeiten im Einzelschritt durch zu probieren. Dann stellt man schnell fest, ob die FPU aktiviert wir oder nicht. Ein Blick in den erweiterten &#039;&#039;&#039;&#039;&#039;Build-Log&#039;&#039;&#039;&#039;&#039; gibt auch schnell Aufschluss darüber, wie der Compiler aufgerufen wird (siehe Kapitel [http://www.mikrocontroller.net/articles/STM32_-_Einstieg_mit_Em::Blocks#Compilieren Compilieren]).&lt;br /&gt;
&lt;br /&gt;
====Test Programm für die FPU====&lt;br /&gt;
Hier ein kleines Testprogramm, dass misst wie viele Taktzyklen für eine Gleitkomma-Multiplikation gebraucht werden. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define CORE_SysTickEn()    (*((u32*)0xE0001000)) = 0x40000001&lt;br /&gt;
#define CORE_SysTickDis()   (*((u32*)0xE0001000)) = 0x40000000&lt;br /&gt;
#define CORE_GetSysTick()   (*((u32*)0xE0001004))&lt;br /&gt;
&lt;br /&gt;
uint32_t t1, t2, dt;&lt;br /&gt;
float x, y, z;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    x = 53.64f;&lt;br /&gt;
    y = 0.27f;&lt;br /&gt;
&lt;br /&gt;
    CORE_SysTickEn();&lt;br /&gt;
    t1 = CORE_GetSysTick();&lt;br /&gt;
&lt;br /&gt;
    z = x * y;&lt;br /&gt;
&lt;br /&gt;
    t2 = CORE_GetSysTick();&lt;br /&gt;
    CORE_SysTickDis();&lt;br /&gt;
&lt;br /&gt;
    dt = (t2 - t1) - 9; //9 Takt-Zyklen werden für die Messung gebraucht &lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Core-Coupled-RAM verwenden===&lt;br /&gt;
Auf den normale SRAM kann durch den Core und die verschiedenen DMA-Controller zugegriffen werden. Jedoch können Core und DMA nicht gleichzeitig auf den SRAM zugreifen. Deswegen gibt es einen zweiten kleinen RAM, den Core-Coupled-RAM (CCRAM), auf den nur vom Core zugegriffen werden kann und nicht von einem DMA-Controller. Der CCRAM ist über einen anderen Bus an dem Cortex angeschlossen. Daduch wird ermöglicht, dass der Core sinnvoll weiterarbeiten kann, wenn ein DMA-Controller Daten aus den &amp;quot;Haupt&amp;quot;-RAM ließt/schreibt, indem der Core Daten aus dem CCRAM verarbeitet. Um Daten in den CCRAM zu legen, geht man wie folgt vor:&lt;br /&gt;
&lt;br /&gt;
1. Eine neue Section im Linkerscript anlegen:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
Sections:&lt;br /&gt;
{&lt;br /&gt;
  ...&lt;br /&gt;
&lt;br /&gt;
  .ccram :&lt;br /&gt;
  {&lt;br /&gt;
    *(.ccram)&lt;br /&gt;
  } &amp;gt; CCRAM&lt;br /&gt;
&lt;br /&gt;
  ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Um die neue Section zu verwenden benutzt man diesen Define:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#define CCRAM __attribute__((section(&amp;quot;.ccram&amp;quot;)))&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
int CCRAM dataInCCRAM1;&lt;br /&gt;
char CCRAM dataInCCRAM2;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Booten aus dem SRAM==&lt;br /&gt;
STM32 Controller haben die Möglichkeit Code aus dem Flash als auch aus dem SRAM auszuführen. Um eine Anwenung per Debugger in des SRAM zu laden sind nur wenige Schritte erforderlich:&lt;br /&gt;
&lt;br /&gt;
*Um das Linkerscript für den SRAM zu verwenden geht man zu: &#039;&#039;&#039;&#039;&#039;Build options... -&amp;gt; Device&#039;&#039;&#039;&#039;&#039; dort wählt man unter &#039;&#039;&#039;&#039;&#039;Policy&#039;&#039;&#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;Use target settings&#039;&#039;&#039;&#039;&#039; aus und übernimmt die vorherigen Einstellungen, nur unter &#039;&#039;&#039;&#039;&#039;Linker script*&#039;&#039;&#039;&#039;&#039; gibt man &#039;&#039;&#039;&#039;&#039;.\stm32f407vg_sram.ld&#039;&#039;&#039;&#039;&#039; an&lt;br /&gt;
&lt;br /&gt;
*Dann muss man noch unter &#039;&#039;&#039;&#039;&#039;Debug -&amp;gt; Interfaces -&amp;gt; Settings&#039;&#039;&#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;Vector table start&#039;&#039;&#039;&#039;&#039; auf 0x20000000 ändern und &#039;&#039;&#039;&#039;&#039;Execute from RAM&#039;&#039;&#039;&#039;&#039; auswählen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:bootsram_1.png Booten aus dem SRAM]] [[Datei:bootsram_2.png Booten aus dem SRAM]]&lt;br /&gt;
&lt;br /&gt;
Anschließend kann man die Anwendung ganz normal debuggen. Nach einem Reset muss die Anwenung erneut mit dem Debugger gestartet werden.&lt;br /&gt;
&lt;br /&gt;
=Fortsetzung folgt..=&lt;br /&gt;
Kritik, Wünsche usw. sind gerne erwünscht, am besten hier in den Thread posten: [http://www.mikrocontroller.net/topic/323750 Neues STM32 Tutorial]&lt;br /&gt;
&lt;br /&gt;
[[Category:ARM]]&lt;br /&gt;
[[Category:STM32]]&lt;/div&gt;</summary>
		<author><name>Avrprogger</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=STM32_-_Einstieg_mit_Em::Blocks&amp;diff=81859</id>
		<title>STM32 - Einstieg mit Em::Blocks</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=STM32_-_Einstieg_mit_Em::Blocks&amp;diff=81859"/>
		<updated>2014-02-28T15:29:49Z</updated>

		<summary type="html">&lt;p&gt;Avrprogger: /* Die FPU */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In diesem Tutorial werde ich versuchen, möglichst einfach, die ersten Schritte zur Entwicklung von STM32 Anwenungen mit der Em::Blocks IDE zu erklären. Hier soll nicht so stark auf die einzelnen Peripherie-Module der Controller eingegangen werden, sondern mehr auf die IDE und die verschieden Libraries, wie die CMSIS Library, die DSP-Library, die Standard-Peripheral-Library, die USB-Library und vllt. über Ethernet. Ich denke ein Kapitel zu FreeRTOS wird es auch geben. Auserdem steht im Vordergrund Sachen wie z.B. booten aus dem SRAM, In-Application-Programming, FPU, Core-Coupled-RAM usw. Mal sehn wie weit ich komme ;)&lt;br /&gt;
&lt;br /&gt;
==Die Entwicklungsumgebung==&lt;br /&gt;
===Hardware===&lt;br /&gt;
Zum testen der Anwendungen, benutze ich das STM32F4-Discovery Board, welches einen Debugger, Peripherie und natürlich einen STM32 Controller (STM32F407VGT6) enthält. Deshalb sind alle Beispiele hier für den STM32F407VG Controller ausgelegt, können aber meisten 1:1 auf andere Controller portiert werden. Ich werde auch möglichsts keine STM32F4-Discovery Board spezifischen Libraries verwenden, damit der Portierungs-Vorgang möglichsts einfach bleibt.&lt;br /&gt;
&lt;br /&gt;
===Software===&lt;br /&gt;
In diesem Tutorial verwende ich [http://www.emblocks.org/ Em::Blocks] als IDE. Em::Blocks ist eine kostenlose, uneingeschränkte IDE, die alle STM32 Mikrcontroller unterstützt und sehr einfach zu bedienen ist.&lt;br /&gt;
nach dem Download kann die IDE per Dialog, sehr einfach, installiert werden. Als Compiler beinhaltet Em::Blocks den &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
Die IDE unterstützt zurzeit den ST-Link, den J-Link und es gibt eine Generic-Vorlage, durch welche andere Debugger konfiguriert werden können.&lt;br /&gt;
&lt;br /&gt;
Außerdem muss noch der passende Treiber für den Debugger installiert werden. Verwendet man ein Discovery-Board muss der [http://www.st.com/web/catalog/tools/FM146/CL1984/SC724/SS1677/PF251168 ST-Link/V2]-Treiber heruntergeladen und installiert werden. (Die Installation muss evtl. als Administrator ausgeführt werden, da sonst die Installation unvollständig wird.) Nach der Installation des Treibers kann man den Debugger über die entsprechende USB Schnittstelle an den PC anschließen und es sollte die Meldung von Windows kommen, dass der richtige Treiber gefunden wurde.&lt;br /&gt;
&lt;br /&gt;
===Libraries===&lt;br /&gt;
Zum programmieren benötigt man noch die [http://www.arm.com/products/processors/cortex-m/cortex-microcontroller-software-interface-standard.php CMSIS] und die Standard-Peripheral-Library (z.B. für die F4 Controller [http://www.st.com/stonline/stappl/productcatalog/app?page=partNumberSearchPage&amp;amp;levelid=SS1577&amp;amp;parentid=1743&amp;amp;resourcetype=SW Standard-Peripheral-Library-F4]), die man am besten in einen Ordner (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\STM32&#039;&#039;&#039;&#039;&#039;) entpackt&lt;br /&gt;
&lt;br /&gt;
==Basis-Wissen zur IDE==&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von Dateien zum Projekt===&lt;br /&gt;
Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf &amp;lt;ProjektName&amp;gt; -&amp;gt; Add files...&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Enfernen von Dateien aus dem Projekt===&lt;br /&gt;
Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf die Datei / mehrere Dateien auswählen -&amp;gt; Remove file from project&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
Die Dateien werden lediglich aus dem Projekt entfernt und nicht von der Festplatte gelöscht.&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von Include-Pfaden===&lt;br /&gt;
Sofern die Include-Datei(en) nicht im standard Include-Ordner &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; des Projektes liegen, muss man den Pfad zum Projekt hinzufügen, damit der Compiler die Include-Dateien später auch finden kann. Man geht wie folgt vor: Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; Search Directories -&amp;gt; Add&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von globalen Defines zum Build===&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; #defines&#039;&#039;&#039;&#039;&#039; können globale Defines hinzugefügt werden.&lt;br /&gt;
&lt;br /&gt;
===Compilieren===&lt;br /&gt;
Entweder über das &#039;&#039;&#039;&#039;&#039;Build&#039;&#039;&#039;&#039;&#039; Menü oder über &#039;&#039;&#039;&#039;&#039;F7&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Um eine genau Ausgabe des Compiler-Aufrufes mit allen Argumenten zu bekommen, geht man im &#039;&#039;&#039;&#039;&#039;Settings&#039;&#039;&#039;&#039;&#039; Menü auf &#039;&#039;&#039;&#039;&#039;Tools...&#039;&#039;&#039;&#039;&#039; und dann auf &#039;&#039;&#039;&#039;&#039;Toolchain executables&#039;&#039;&#039;&#039;&#039;. Ganz unten, unter &#039;&#039;&#039;&#039;&#039;Logging&#039;&#039;&#039;&#039;&#039; kann man dann &#039;&#039;&#039;&#039;&#039;Full command line&#039;&#039;&#039;&#039;&#039; auswählen.&lt;br /&gt;
&lt;br /&gt;
====Compiler Optionen====&lt;br /&gt;
=====Optimierung=====&lt;br /&gt;
Standardmäßig verwendet Em::Blocks keine Optimierung. Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; Categories: Optimization&#039;&#039;&#039;&#039;&#039; kann zwischen verschieden Optimierungen ausgewählt werden.&lt;br /&gt;
&lt;br /&gt;
=====Verschiedene C-Standards=====&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; Categories: Language standard&#039;&#039;&#039;&#039;&#039; kann man zwischen verschieden C-Standard auswählen, wie z.B, C99.&lt;br /&gt;
(Mit C99 können auch die Lauf-Variable in der for-Schleife deklariert werden: for(int i;..))&lt;br /&gt;
&lt;br /&gt;
===Debuggen===&lt;br /&gt;
*Als erstes den Debugger starten über das &#039;&#039;&#039;&#039;&#039;Debug&#039;&#039;&#039;&#039;&#039; Menü und &#039;&#039;&#039;&#039;&#039;Start/stop Debug Session&#039;&#039;&#039;&#039;&#039; oder über &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
*Danach läuft die Anwendung auf dem Controller und warten im &#039;&#039;&#039;&#039;&#039;Reset_Handler&#039;&#039;&#039;&#039;&#039; auf Einzelschritt- bzw. Run- Befehle (&#039;&#039;&#039;&#039;&#039;F5, F10, F11&#039;&#039;&#039;&#039;&#039; usw..(siehe &#039;&#039;&#039;&#039;&#039;Debug-Menü&#039;&#039;&#039;&#039;&#039; für alle Möglichkeiten))&lt;br /&gt;
&lt;br /&gt;
*Mit &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039; wird die Debug-Session auch wieder beendet&lt;br /&gt;
&lt;br /&gt;
*Unter &#039;&#039;&#039;&#039;&#039;Debug -&amp;gt; Interfaces -&amp;gt; Target settings&#039;&#039;&#039;&#039;&#039; können Eigenschaften, wie z.B &#039;&#039;&#039;&#039;&#039;Run to main()&#039;&#039;&#039;&#039;&#039; aktiviert werden.&lt;br /&gt;
&lt;br /&gt;
===Projekt als Template abspeichern===&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;File -&amp;gt; Save project as template...&#039;&#039;&#039;&#039;&#039;. Das Template erscheint dann im Projekt-Dialog unter &#039;&#039;&#039;&#039;&#039;User templates&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Das erste Projekt erstellen==&lt;br /&gt;
Hier erkläre ich, wie man am Besten (aus meiner Sicht), ein neues Projekt von Grund auf erstellt, sodass man hinterher, den Controller-Kern über die CMSIS-Library und die Peripherie über die Register steuern kann.&lt;br /&gt;
&lt;br /&gt;
===1. Projekt mit der IDE erstellen===&lt;br /&gt;
Nach der Installation der oben beschriebenen Komponenten erstellt man am besten ein Verzeichnis (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\EmBlocks&#039;&#039;&#039;&#039;&#039;), indem später alle Projekte gespeichert werden. Für Libraries kann man auch noch ein Verzeichnis (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\STM32&#039;&#039;&#039;&#039;&#039;) erstellen, wo alle Libraries gespeichert werden, die man für die Projekt brauchen.&lt;br /&gt;
&lt;br /&gt;
Als nächstes starten man EmBlocks. Bei dem ersten Start öffnet sich ein Fenster, wo verschiedene Compiler angezeigt werden, die Em::Blocks findet. Dort wählt man den &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039; aus und klickt &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039;. Nun sollte sich das Hauptfenster von Em::Blocks öffnen. Über &#039;&#039;&#039;&#039;&#039;Create a new Project&#039;&#039;&#039;&#039;&#039; oder &#039;&#039;&#039;&#039;&#039;File -&amp;gt; New -&amp;gt; Project&#039;&#039;&#039;&#039;&#039; ruft man den Projekt-Dialog auf und kann ein neues Projekt erzeugen.&lt;br /&gt;
&lt;br /&gt;
Auf der Ersten Seite wählen man den &#039;&#039;&#039;&#039;&#039;STmicro-ARM&#039;&#039;&#039;&#039;&#039; Projekt-Typ aus.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_1.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auf der nächsten Seite wird man darauf hingewiesen, dass das der entsprechende Projekt-Typ-Dialog ausgeführt wird. Hier kann man ein Häkchen bei &#039;&#039;&#039;&#039;&#039;Skip this page next time&#039;&#039;&#039;&#039;&#039; setzen und auf &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; klicken.&lt;br /&gt;
&lt;br /&gt;
Im nächsten Schritt wählen man das zuvor erstellt Verzeichnis unter &#039;&#039;&#039;&#039;&#039;Folder to create Project in&#039;&#039;&#039;&#039;&#039; aus, indem später alle Projekt gespeichert werden. Außerdem geben wir dem Projekt einen Namen (z.B. &#039;&#039;&#039;&#039;&#039;FirstProject&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_2.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danach muss man einen Compiler auswählen und bestimmen, welche Projekt-Konfigurationen erszeugt werden sollen. Unter &#039;&#039;&#039;&#039;&#039;Compiler&#039;&#039;&#039;&#039;&#039; wählt man &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039; und man kann das Häkchen bei &#039;&#039;&#039;&#039;&#039;Create &amp;quot;Release&amp;quot; configuration&#039;&#039;&#039;&#039;&#039; entfernen, da diese unnötig ist, die Debug-Konfiguration sollte eig. immer ausreichen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_3.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auf den folgenden Seite wird der Controller ausgewählt. Verwendet man ein STM32F4-Discovery Board müssen folgende Dinge gewählt werden: &#039;&#039;&#039;&#039;&#039;Cortex_M4 (F3xx - F4xx) -&amp;gt; STM32F4xx (Cortex M4 with FPU) -&amp;gt; STM32F407VG&#039;&#039;&#039;&#039;&#039;. Leider sind die Auswahl Möglichkeiten nicht ganz richtig, da auch die F3 Controller einen Cortex M4 Kern und eine FPU haben (Ist aber nicht so wichtig, ist nur eine formale Sache). Außerdem entfernt man das Häkchen bei &#039;&#039;&#039;&#039;&#039;Standard Peripherals Library&#039;&#039;&#039;&#039;&#039; (Wie man die Standard-Peripheral-Library einbindet und verwendet erkläre ich später). Man kann auch das Häkchen bei &#039;&#039;&#039;&#039;&#039;Create hex file for Realease target&#039;&#039;&#039;&#039;&#039; entfernen.&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;Stack Size&#039;&#039;&#039;&#039;&#039; und &#039;&#039;&#039;&#039;&#039;Heap Size&#039;&#039;&#039;&#039;&#039; wird die Größe von Stack und Heap festgelegt. Für eine erste Anwendung kann man die Einstellungen so lassen (Stack-Size: 0x0100 =&amp;gt; 256 Byte Stack und Heap-Size: 0x0000 =&amp;gt; kein Heap). Mit &#039;&#039;&#039;&#039;&#039;Finish&#039;&#039;&#039;&#039;&#039; ist der Projekt Dialog abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_4.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danach sollten sich zwei neue Fenster öffnen, um die Debug-Eigenschaften fest zu legen.&lt;br /&gt;
Verwendet man ein Discovery Board/ST-Link müssen die Einstellungen wie auf dem Bild gewählt werden. Über den Button &#039;&#039;&#039;&#039;&#039;Settings&#039;&#039;&#039;&#039;&#039; öffnet sich das zweite Fenster, falls sich dieses nicht schon von alleine öffnen sollte. Nach den Schließen der Fenster über &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; ist der Projekt Dialog beendet und ein neues Projekt steht zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_5_1.png|Debug Eigenschaften 1. Fenster]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_5_2.png|Debug Eigenschaften 2. Fenster]]&lt;br /&gt;
&lt;br /&gt;
===2. CMSIS-Library und Startup-Code hinzufügen===&lt;br /&gt;
Wenn man sich, nachdem man ein neues Projekt in der IDE erstellt hat, die bereits vorhandenen Dateien im Projekt ansieht, stellt man fest, das bereits ein Ordner &#039;&#039;&#039;&#039;&#039;cmsis&#039;&#039;&#039;&#039;&#039; existiert, der einige wichtige Include-Dateien der CMSIS-Library enthält. Allerdings sind das wirklich nur die wichtigsten Include-Dateien der CMSIS-Library und dazu noch, die aus einer älternen Version. Ich ziehe es deshalb vor die &amp;quot;Mini-CMSIS-Libraray&amp;quot; und die &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c/.h&#039;&#039;&#039;&#039;&#039; Dateien des Projektes durch aktuellere Versionen zu ersetzen. So ist später auch die Integration  von anderen Libraries, wie z.B. der CMSIS-DSP-Libarary einfacher.  &lt;br /&gt;
&lt;br /&gt;
Zunächst gehen man in das Projekt-Verzeichnis und löscht:&lt;br /&gt;
*Den Ordner &#039;&#039;&#039;&#039;&#039;cmsis&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Alle Dateien im Include Verzeichnis &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; im &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner&lt;br /&gt;
&lt;br /&gt;
Außerdem entfernt man auch alle gelöschten Dateien in der IDE aus dem Projekt mit &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Rechts Klick -&amp;gt; Remove file from project&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Es sollte folgende Verzeichnis Struktur überbleiben:&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_6.png|Überbleibende Dateien]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Jetzt müssen die gelöschten Dateien durch die aktuelleren ersetzt werden.&lt;br /&gt;
&lt;br /&gt;
*Dazu kopieren man den gesamten Ordner &#039;&#039;&#039;&#039;&#039;CMSIS&#039;&#039;&#039;&#039;&#039; aus dem CMSIS Download in das Projekt Verzeichnis.&lt;br /&gt;
&lt;br /&gt;
*Aus dem Standard-Peripheral-Library Download kopiert man von &#039;&#039;&#039;&#039;&#039;Libraries\CMSIS\Device\ST\STM32F4xx\Include&#039;&#039;&#039;&#039;&#039; alle Dateien in den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projekt Verzeichnisses&lt;br /&gt;
&lt;br /&gt;
*Aus der Standard-Peripheral-Library kopieren man ebenfalls von &#039;&#039;&#039;&#039;&#039;Libraries\CMSIS\Device\ST\STM32F4xx\Source\Templates&#039;&#039;&#039;&#039;&#039; die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; in den &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner des Projekts&lt;br /&gt;
&lt;br /&gt;
Anschließend müssen die neuen Dateien in der IDE dem Projekt hinzugefügt werden. Dazu benutzt man &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Rechts Klick -&amp;gt; Add files&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
*Aus dem &#039;&#039;&#039;&#039;&#039;CMSIS&#039;&#039;&#039;&#039;&#039; Ordner im Projekt Verzeichnis werden aus den Unterorder &#039;&#039;&#039;&#039;&#039;Include&#039;&#039;&#039;&#039;&#039; folgende Dateien dem Projekt hinzugefügt:&lt;br /&gt;
**arm_common_tables.h&lt;br /&gt;
**arm_const_structs.h&lt;br /&gt;
**arm_math.h&lt;br /&gt;
**core_cm4.h&lt;br /&gt;
**core_cm4_simd.h&lt;br /&gt;
**core_cmFunc.h&lt;br /&gt;
**core_cmInstr.h&lt;br /&gt;
*Alle Dateien aus den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projektes&lt;br /&gt;
*Die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; aus dem &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner&lt;br /&gt;
&lt;br /&gt;
So sollte die Struktur dann aussehen:&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_7.png|Anwenungs-Grundgerüst]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Da einige Dateien der Libraries später bearbeitet werden müssen und Schreibgeschützt sind, weise ich hier schonmal darauf hin, das der Schreibschutz in der IDE über &#039;&#039;&#039;&#039;&#039;Rechts Klick auf die Datei -&amp;gt; Properties -&amp;gt; Häkchen bei &amp;quot;File is read only&amp;quot; entfernen&#039;&#039;&#039;&#039;&#039; entfert werden kann.&lt;br /&gt;
&lt;br /&gt;
Damit die IDE die Header-Dateien der CMSIS Library auch finden kann, weil diese ja nicht im standard Include Ordner &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; liegen, muss unter &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Build Options -&amp;gt; Search Directories&#039;&#039;&#039;&#039;&#039; der Pfad &#039;&#039;&#039;&#039;&#039;CMSIS\Include&#039;&#039;&#039;&#039;&#039; hinzugefügt werden.&lt;br /&gt;
&lt;br /&gt;
Compiliert man jetzt das Projekt mit &#039;&#039;&#039;&#039;&#039;F7&#039;&#039;&#039;&#039;&#039; gibt es ein paar Fehler Meldungen, weil keine Controller-Reihe ausgewählt wurde. Ebenfalls unter &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Build Options -&amp;gt; Compiler Settings -&amp;gt; #defines&#039;&#039;&#039;&#039;&#039; wird der Define &#039;&#039;&#039;&#039;&#039;STM32F40_41xxx&#039;&#039;&#039;&#039;&#039; hinzugefügt.&lt;br /&gt;
&lt;br /&gt;
Beim erneuten Compilieren sollten sich nun keine neuen Fehler ergeben.&lt;br /&gt;
&lt;br /&gt;
===3. Das erste Programm===&lt;br /&gt;
Nachdem ein grundsätzliches &amp;quot;Gerüst&amp;quot; fertig ist, kann man den ersten Code schreiben.&lt;br /&gt;
main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC-&amp;gt;AHB1ENR |= RCC_AHB1ENR_GPIODEN;    //Takt für GPIO aktivieren&lt;br /&gt;
    GPIOD-&amp;gt;MODER |= GPIO_MODER_MODER15_0;   //GPIOD Pin15 als Ausgang&lt;br /&gt;
    GPIOD-&amp;gt;BSRRL |= GPIO_BSRR_BS_15;        //GPIOD Pin15 auf High ziehen&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039; wird dann der Debugger gestartet. Hat der Debugger das Projekt erfolgreich übertragen kann die Ausführung mit &#039;&#039;&#039;&#039;&#039;F5&#039;&#039;&#039;&#039;&#039; begonnen werden.&lt;br /&gt;
&lt;br /&gt;
==Libraries einbinden/verwenden==&lt;br /&gt;
Um Libraries, wie hier im Tutorial, einzubinden, wird ein existierendes Projekt, wie ein im Kapitel [http://www.mikrocontroller.net/articles/STM32_-_Einstieg_mit_Em::Blocks#Das_erste_Projekt_erstellen Das Erste Projekt erstellen] beschrieben wird, vorausgesetzt.&lt;br /&gt;
&lt;br /&gt;
===Einbinden der Standard-Peripheral-Library===&lt;br /&gt;
Um nicht immer die einzelnen Register, wie im ersten &amp;quot;bare-metal&amp;quot; Beispiel, aus dem Reference-Manual zu suchen und zu beschreiben, gibt es von ST die Standard Peripheral Library, die diese Aufgaben übernimmt und mit der sich die &amp;quot;normale/grundlegende&amp;quot; (Alles außer USB und Ethernet) Peripherie recht einfach steuern lässt. Ich kopiere die Standard-Peripheral-Library immer per Hand in das Projekt. Darduch hat man auch gleich die aktuellste Version (in den älteren Version gibt es einige Bugs). &lt;br /&gt;
&lt;br /&gt;
*1. Den Ordner &#039;&#039;&#039;&#039;&#039;Libraries\STM32F4xx_StdPeriph_Driver&#039;&#039;&#039;&#039;&#039; aus dem Standard-Peripheral-Library Download in das Projekt-Verzeichnis kopieren&lt;br /&gt;
*2. Die Datei &#039;&#039;&#039;&#039;&#039;Project\STM32F4xx_StdPeriph_Templates\stm32f4xx_conf.h&#039;&#039;&#039;&#039;&#039; ebenfalls aus dem Standard-Peripheral-Library Download in den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projektes kopieren.&lt;br /&gt;
*3. In der IDE den Include-Path &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\inc&#039;&#039;&#039;&#039;&#039; hinzufügen&lt;br /&gt;
*4. Und das/den Define &#039;&#039;&#039;&#039;&#039;USE_STDPERIPH_DRIVER&#039;&#039;&#039;&#039;&#039; hinzufügen&lt;br /&gt;
*4. Source- und Include-Dateien zum Projekt hinzufügen&lt;br /&gt;
**Achtung: Es dürfen nur die Dateien hinzugefügt werden, für die der Controller auch die entsprechende Peripherie bereit stellt. Diese Dateien dürfen nicht beim STM32F4-Discovery/STM32F407VG hinzugefügt werden.&lt;br /&gt;
***stm32f4xx_dma2d.c/.h&lt;br /&gt;
***stm32f4xx_fmc.c/.h&lt;br /&gt;
***stm32f4xx_ltdc.c/.h&lt;br /&gt;
***stm32f4xx_sai.c/.h&lt;br /&gt;
&lt;br /&gt;
Daraus resultiert folgende Struktur:&lt;br /&gt;
&lt;br /&gt;
[[Datei:stdperiphlib_2.png|Header-Struktur]] [[Datei:stdperiphlib_1.png|Source-Struktur]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Anschließen kann die Standard-Peripheral-Library benutz werden.&lt;br /&gt;
main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);&lt;br /&gt;
&lt;br /&gt;
    GPIO_InitTypeDef GPIOD_InitStructure;&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Mode = GPIO_Mode_OUT;     //Als Ausgang&lt;br /&gt;
    GPIOD_InitStructure.GPIO_OType = GPIO_OType_PP;    //Push-Pull Betrieb&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Pin = GPIO_Pin_15;        //Pin 15 (STM32F4-Discovery: Blaue LED)&lt;br /&gt;
    GPIOD_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;  //Kein Pull-Up oder Pull-Down Widerstand aktiviert&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Speed = GPIO_Speed_25MHz; //25MHz Update-Rate&lt;br /&gt;
    GPIO_Init(GPIOD, &amp;amp;GPIOD_InitStructure);&lt;br /&gt;
&lt;br /&gt;
    GPIO_SetBits(GPIOD, GPIO_Pin_15);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hier ist noch ein &amp;quot;BasicFramework&amp;quot;, dass die komplette CMSIS- und Standard-Peripheral-Library enthält und kann Quasi als Basis für alle Projekte verwendet werden. Allerdings ist das Framework primär auf die STM32F405/7 und STM32F415/7 ausgelegt. Die neueren STM32F401, STM32F42X und STM32F43X  haben noch etwas andere Peripherie, dass Framework müsste dann entsprechend angepasst werden. Download: [[Datei:StdPeriphDriver_BasicFramework.zip]]&lt;br /&gt;
&lt;br /&gt;
===Einbinden der DSP-Library===&lt;br /&gt;
STM32F3 / STM32F4 Microcontroller haben neben der FPU noch einen Digital-Signal-Processor (DSP). Die DSP dient hauptsächlich dazu, viele Daten schnell zu verarbeiten (z.B. Video- oder Audiosignal). Der CMSIS-Download beinhaltet dazu neben der eigentlichen CMSIS-Library auch noch eine DSP-Library. Diese Library stellt sowohl einfache, mathematische Funktionen wie addieren, multiplizieren usw. als auch komplexe Funktionen, wie z.B  einen IIR-Filter, zur Verfügung. Die DSP-Library ist weiter aufgeteilt in kleinere Module, wie z.B. BasicMathFunctions, FilteringFunctions usw. (siehe &#039;&#039;&#039;&#039;&#039;CMSIS\DSP-Library\Source&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
*1. Source-Dateien des benötigten Moduls zum Projekt hinzufügen. (&#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Add files...&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
*2. &#039;&#039;&#039;&#039;&#039;arm_math.h&#039;&#039;&#039;&#039;&#039; in der &#039;&#039;&#039;&#039;&#039;main.c&#039;&#039;&#039;&#039;&#039; einbinden&lt;br /&gt;
*3. Damit die Warnung &amp;quot;Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)&amp;quot; verschwindet, muss der Define &#039;&#039;&#039;&#039;&#039;__FPU_PRESENT&#039;&#039;&#039;&#039;&#039; hinzugefügt werden. (Keine Ahnung, wieso es die Warnung gibt)&lt;br /&gt;
 &lt;br /&gt;
Jetzt kann die DSP-Library verwedet werden. Das Beispiel multipliziert zwei Buffer miteinander. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
#include &amp;quot;arm_math.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    float32_t x[1024];&lt;br /&gt;
    float32_t y[1024];&lt;br /&gt;
    float32_t z[1024];&lt;br /&gt;
&lt;br /&gt;
    for(uint16_t i = 0; i &amp;lt; 1024; i++)&lt;br /&gt;
    {&lt;br /&gt;
        x[i] = i;&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for(uint16_t i = 0; i &amp;lt; 1024; i++)&lt;br /&gt;
    {&lt;br /&gt;
        y[i] = PI;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    arm_mult_f32(x, y, z, 1024);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Startup-Code, Linker-Script, Takt, FPU usw.==&lt;br /&gt;
===Startup-Code===&lt;br /&gt;
Em::Blocks fügt standardmäßig einen Startup-Code mit in das Projekt ein. Die wichtigsten Dinge die darin erledigt werden sind folgende:&lt;br /&gt;
&lt;br /&gt;
*Stack und Heap wird angelgt&lt;br /&gt;
*Die Vector-Table wird angelegt&lt;br /&gt;
*Ein Default Reset-Handler wird implementiert, dieser erledigt folgende aufgaben:&lt;br /&gt;
**Kopieren der definierten Daten aus dem Flash in den SRAM&lt;br /&gt;
**&#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; wird aufgerufen, wenn &#039;&#039;&#039;&#039;&#039;__NO_SYSTEM_INIT&#039;&#039;&#039;&#039;&#039; nicht definiert ist&lt;br /&gt;
**Sprung in die &#039;&#039;&#039;&#039;&#039;main()&#039;&#039;&#039;&#039;&#039; Funktion&lt;br /&gt;
*Allen anderen Interrupt-Handler wird eine Default-Funktion &#039;&#039;&#039;&#039;&#039;def_irq_handler&#039;&#039;&#039;&#039;&#039; mit einer &#039;&#039;&#039;&#039;&#039;while(1)&#039;&#039;&#039;&#039;&#039;-Schleife zugewiesen, falls kein anderer Interrupt-Handler existiert.&lt;br /&gt;
&lt;br /&gt;
Normalerweise muss am Startup-Code nichts verändert werden.&lt;br /&gt;
&lt;br /&gt;
===Linker-Script===&lt;br /&gt;
Em::Blocks stellt zwei fertige Linker-Scripts bereit, eins für die Ausführung des Programmes aus dem Flash (&#039;&#039;&#039;&#039;&#039;*_flash.ld&#039;&#039;&#039;&#039;&#039;), das andere für die Ausführung aus dem SRAM (&#039;&#039;&#039;&#039;&#039;*_sram.ld&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Normalerweise muss auch hier nichts geändert werden, es sei den Daten sollen in bestimmten Adressbereichen abgelegt werden (z.B. im Core-Coupled RAM), was ich später noch zum Tutorial hinzufüge.&lt;br /&gt;
&lt;br /&gt;
===Der Takt===&lt;br /&gt;
Jeder Controller oder Prozessor braucht einen Takt, indem er die einzelnen Maschinen-Befehle abarbeiten kann.&lt;br /&gt;
Bei den STM32 Mikrocontrollern kann dieser Takt aus verschiedenen Quellen kommen:&lt;br /&gt;
&lt;br /&gt;
1. High Speed Internal Oszillator (HSI)&lt;br /&gt;
&lt;br /&gt;
2. High Speed External Oszillator (HSE)&lt;br /&gt;
&lt;br /&gt;
3. Low Speed Internal Oszillator (LSI)&lt;br /&gt;
&lt;br /&gt;
4. Low Speed External Oszillator (LSE)&lt;br /&gt;
&lt;br /&gt;
5. Phase-Locked Loop (PLL) (generiert den Takt aus den ersten vier Taktquellen durch Teiler und Faktoren)&lt;br /&gt;
&lt;br /&gt;
Nach einem Reset wird der Controller aus der HSI Taktquelle versorgt (16MHz beim STM32F407VG). Um die voll Performance des Controllers zu erreichen muss die PLL verwendet werden, welche den Takt durch geschickte Teiler und Faktoren vervielfältigt, sodass am Ende der Controller mit der maximalen Taktfrequenz läuft. Die notwendige Initialisierung der PLL findet in der Funktion &#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; statt. Die PLL erzeugt zunächst einen Basistakt:&lt;br /&gt;
&lt;br /&gt;
PLL_VCO = (F_HSE / PLL_M) * PLL_N&lt;br /&gt;
&lt;br /&gt;
Aus diesem Takt wird dann der Takt für den Controller-Kern abgeleitet:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = PLL_VCO / PLL_P&lt;br /&gt;
&lt;br /&gt;
Und der Takt für SDIO / USB / RNG (48MHz):&lt;br /&gt;
&lt;br /&gt;
48MHz = PLL_VCO / PLL_Q&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Durch weiter Teiler werden, die Takte für die einzelnen Busse erzeugt, da diese nicht alle beliebig schnell betrieben werden dürfen.&lt;br /&gt;
&lt;br /&gt;
Genaue Angaben findet man zu dem jeweiligen Clock-System des Controllers im Reference Manual.&lt;br /&gt;
&lt;br /&gt;
Ein Blick in den &amp;quot;Kommentar-Header&amp;quot; verrät, dass von einem externen (HSE) Oszillator von 25MHz ausgegangen wird, der die PLL versorgen soll.&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((25MHz / PLL_M(25)) * PLL_N(336)) / PLL_P(2) = 168MHz&lt;br /&gt;
&lt;br /&gt;
Allerdings stimmt diese Rechnung natürlich nur, wenn wirklich ein 25MHz Quarz am Controller angeschlossen ist. Auf dem STM32F4-Discovery Board befindet sich aber nur ein 8MHz Quarz. Demnach gilt:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((8MHz / PLL_M(25)) * PLL_N(336)) / PLL_P(2) = 53.76MHz&lt;br /&gt;
&lt;br /&gt;
Der Controller läuft also nur mit 53.76MHz, wenn wie ober beschrieben ein Projekt erstellt wird. Allerdings kann dieses Problem durch ändern von den betroffen Defines behoben werden:&lt;br /&gt;
 &lt;br /&gt;
*Dazu geht man in die &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; Datei und passt zur Vollständigkeit erstmal die zum Controller passende Tabelle im &amp;quot;Kommentar-Header&amp;quot; an (Z.57f):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      HSE Frequency(Hz)                      | 8000000&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      PLL_M                                  | 8&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Danach passt man den PPL_M Define (Z.254) an:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/************************* PLL Parameters *************************************/&lt;br /&gt;
/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */&lt;br /&gt;
#define PLL_M      8&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Außerdem muss man den HSE_VALUE Define in der &#039;&#039;&#039;&#039;&#039;inc/stm32f4xx.h&#039;&#039;&#039;&#039;&#039; angepasst werden (Z.122):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#if !defined  (HSE_VALUE)&lt;br /&gt;
  #define HSE_VALUE    ((uint32_t)8000000) /*!&amp;lt; Value of the External oscillator in Hz */&lt;br /&gt;
&lt;br /&gt;
#endif /* HSE_VALUE */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine neue Berechnung zeigt:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((8MHz / PLL_M(8)) * PLL_N(336)) / PLL_P(2) = 168MHz&lt;br /&gt;
&lt;br /&gt;
Jetzt läuft der Controller mit maximaler Geschwindigkeit.&lt;br /&gt;
&lt;br /&gt;
Die Theorie wird durch folgendes Programm verifiziert. Der geviertelte System-Takt SYSCLK wir am Pin PC9 ausgegeben. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);&lt;br /&gt;
&lt;br /&gt;
    GPIO_InitTypeDef GPIOC_InitStructure;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Mode = GPIO_Mode_AF;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_OType = GPIO_OType_PP;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Pin = GPIO_Pin_9;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;&lt;br /&gt;
    GPIO_Init(GPIOC, &amp;amp;GPIOC_InitStructure);&lt;br /&gt;
&lt;br /&gt;
    RCC_MCO2Config(RCC_MCO2Source_SYSCLK, RCC_MCO2Div_4);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Die FPU===&lt;br /&gt;
====Allgemeines====&lt;br /&gt;
STM32F3 und STM32F4 Controller haben eine FPU.&lt;br /&gt;
Damit die FPU richtig verwendet wird, müssen normalerweise zwei Bedingungen erfüllt sein:&lt;br /&gt;
&lt;br /&gt;
1. Der Controller muss die FPU Hardware-seitig aktivieren&lt;br /&gt;
&lt;br /&gt;
2. Damit die FPU auch was zu tuen bekommt, müssen vom Compiler FPU-Instructions erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
Die Em::Blocks IDE verwendet standardmäßig die FPU, wenn eine Vorhanden ist. Hier wird die FPU Hardware-seitig aktiviert (&#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; Z.341):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* FPU settings ------------------------------------------------------------*/&lt;br /&gt;
  #if (__FPU_PRESENT == 1) &amp;amp;&amp;amp; (__FPU_USED == 1)&lt;br /&gt;
    SCB-&amp;gt;CPACR |= ((3UL &amp;lt;&amp;lt; 10*2)|(3UL &amp;lt;&amp;lt; 11*2));  /* set CP10 and CP11 Full Access */&lt;br /&gt;
  #endif&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
__FPU_PRESENT wird in der &#039;&#039;&#039;&#039;&#039;stm32f4xx.h&#039;&#039;&#039;&#039;&#039; definiert.&lt;br /&gt;
__FPU_USED wird von der IDE übernommen (siehe Build-Log): &#039;&#039;&#039;&#039;&#039;-D__FPU_USED&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Außerdem wird der Compiler von der IDE standardmäßig mit dem Argument &#039;&#039;&#039;&#039;&#039;-mfloat-abi=hard&#039;&#039;&#039;&#039;&#039; aufgerufen, wodurch FPU-Instructions erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
====FPU abschalten====&lt;br /&gt;
Um die FPU ab zu schalten (Mir würde jetzt nur Strom sparen als Grund einfallen) geht man wie folgt vor:&lt;br /&gt;
&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; Device -&amp;gt; Policy&#039;&#039;&#039;&#039;&#039; wählt man &#039;&#039;&#039;&#039;&#039;Use target settings&#039;&#039;&#039;&#039;&#039; und über nimmt die Einstellungen, die vorher dort eingetragen waren, allerdings lässt man das Feld &#039;&#039;&#039;&#039;&#039;FP-hardware&#039;&#039;&#039;&#039;&#039; frei.&lt;br /&gt;
&lt;br /&gt;
[[Datei:fpu_1.png|FPU Abschalten Schritt 1]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;Compiler Settings -&amp;gt; Policy&#039;&#039;&#039;&#039;&#039; wählt man dann &#039;&#039;&#039;&#039;&#039;Use target options only&#039;&#039;&#039;&#039;&#039;. Dann kann man unter &#039;&#039;&#039;&#039;&#039;Categories&#039;&#039;&#039;&#039;&#039; die Option &#039;&#039;&#039;&#039;&#039;ARM FPU architecture&#039;&#039;&#039;&#039;&#039; auswählen. Dort stehen dann drei Möglichkeiten für die FPU zur Verfügung:&lt;br /&gt;
&lt;br /&gt;
1. Software-FPU-Library für Gleitkomma-Berechnung verwenden - Keine FPU-Instructions werden generiert (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=soft&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
2. Eine Mischung aus Software- und Hardware-FPU wird verwendet (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=softfp&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
3. Hardware-FPU wird für Gleitkomma-Berechnungen verwendet (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=hard&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
[[Datei:fpu_2.png|FPU Abschalten Schritt 2]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Um die FPU ab zu schalten wählt man natürlich die erste Möglichkeit.&lt;br /&gt;
Bei der 2. und 3. Möglichkeit fügt die IDE auch den Define &#039;&#039;&#039;&#039;&#039;__FPU_USED&#039;&#039;&#039;&#039;&#039; hinzu. Bei Der ersten Möglichkeit nicht. Der Code muss also nicht verändert / auskommentiert werden.&lt;br /&gt;
&lt;br /&gt;
Um die FPU wieder zu aktivieren müssen alle Schritte wieder rückgängig gemacht werden.&lt;br /&gt;
&lt;br /&gt;
Am besten ist es einfach mal alle Möglichkeiten im Einzelschritt durch zu probieren. Dann stellt man schnell fest, ob die FPU aktiviert wir oder nicht. Ein Blick in den erweiterten &#039;&#039;&#039;&#039;&#039;Build-Log&#039;&#039;&#039;&#039;&#039; gibt auch schnell Aufschluss darüber, wie der Compiler aufgerufen wird (siehe Kapitel [http://www.mikrocontroller.net/articles/STM32_-_Einstieg_mit_Em::Blocks#Compilieren Compilieren]).&lt;br /&gt;
&lt;br /&gt;
====Test Programm für die FPU====&lt;br /&gt;
Hier ein kleines Testprogramm, dass misst wie viele Taktzyklen für eine Gleitkomma-Multiplikation gebraucht werden. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define CORE_SysTickEn()    (*((u32*)0xE0001000)) = 0x40000001&lt;br /&gt;
#define CORE_SysTickDis()   (*((u32*)0xE0001000)) = 0x40000000&lt;br /&gt;
#define CORE_GetSysTick()   (*((u32*)0xE0001004))&lt;br /&gt;
&lt;br /&gt;
uint32_t t1, t2, dt;&lt;br /&gt;
float x, y, z;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    x = 53.64f;&lt;br /&gt;
    y = 0.27f;&lt;br /&gt;
&lt;br /&gt;
    CORE_SysTickEn();&lt;br /&gt;
    t1 = CORE_GetSysTick();&lt;br /&gt;
&lt;br /&gt;
    z = x * y;&lt;br /&gt;
&lt;br /&gt;
    t2 = CORE_GetSysTick();&lt;br /&gt;
    CORE_SysTickDis();&lt;br /&gt;
&lt;br /&gt;
    dt = (t2 - t1) - 9; //9 Takt-Zyklen werden für die Messung gebraucht &lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Core-Coupled-RAM verwenden===&lt;br /&gt;
Auf den normale SRAM kann durch den Core und die verschiedenen DMA-Controller zugegriffen werden. Jedoch können Core und DMA nicht gleichzeitig auf den SRAM zugreifen. Deswegen gibt es einen zweiten kleinen RAM, den Core-Coupled-RAM (CCRAM), auf den nur vom Core zugegriffen werden kann und nicht von einem DMA-Controller. Der CCRAM ist über einen anderen Bus an dem Cortex angeschlossen. Daduch wird ermöglicht, dass der Core sinnvoll weiterarbeiten kann, wenn ein DMA-Controller Daten aus den &amp;quot;Haupt&amp;quot;-RAM ließt/schreibt, indem der Core Daten aus dem CCRAM verarbeitet. Um Daten in den CCRAM zu legen, geht man wie folgt vor:&lt;br /&gt;
&lt;br /&gt;
1. Eine neue Section im Linkerscript anlegen:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
Sections:&lt;br /&gt;
{&lt;br /&gt;
  ...&lt;br /&gt;
&lt;br /&gt;
  .CCRAM :&lt;br /&gt;
  {&lt;br /&gt;
    *(.CCRAM)&lt;br /&gt;
  } &amp;gt; CCRAM&lt;br /&gt;
&lt;br /&gt;
  ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Um die neue Section zu verwenden benutzt man diesen Define:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#define CCRAM __attribute__((section(&amp;quot;.ccram&amp;quot;)))&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
int CCRAM dataInCCRAM1;&lt;br /&gt;
char CCRAM dataInCCRAM2;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Booten aus dem SRAM==&lt;br /&gt;
STM32 Controller haben die Möglichkeit Code aus dem Flash als auch aus dem SRAM auszuführen. Um eine Anwenung per Debugger in des SRAM zu laden sind nur wenige Schritte erforderlich:&lt;br /&gt;
&lt;br /&gt;
*Um das Linkerscript für den SRAM zu verwenden geht man zu: &#039;&#039;&#039;&#039;&#039;Build options... -&amp;gt; Device&#039;&#039;&#039;&#039;&#039; dort wählt man unter &#039;&#039;&#039;&#039;&#039;Policy&#039;&#039;&#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;Use target settings&#039;&#039;&#039;&#039;&#039; aus und übernimmt die vorherigen Einstellungen, nur unter &#039;&#039;&#039;&#039;&#039;Linker script*&#039;&#039;&#039;&#039;&#039; gibt man &#039;&#039;&#039;&#039;&#039;.\stm32f407vg_sram.ld&#039;&#039;&#039;&#039;&#039; an&lt;br /&gt;
&lt;br /&gt;
*Dann muss man noch unter &#039;&#039;&#039;&#039;&#039;Debug -&amp;gt; Interfaces -&amp;gt; Settings&#039;&#039;&#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;Vector table start&#039;&#039;&#039;&#039;&#039; auf 0x20000000 ändern und &#039;&#039;&#039;&#039;&#039;Execute from RAM&#039;&#039;&#039;&#039;&#039; auswählen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:bootsram_1.png Booten aus dem SRAM]] [[Datei:bootsram_2.png Booten aus dem SRAM]]&lt;br /&gt;
&lt;br /&gt;
Anschließend kann man die Anwendung ganz normal debuggen. Nach einem Reset muss die Anwenung erneut mit dem Debugger gestartet werden.&lt;br /&gt;
&lt;br /&gt;
=Fortsetzung folgt..=&lt;br /&gt;
Kritik, Wünsche usw. sind gerne erwünscht, am besten hier in den Thread posten: [http://www.mikrocontroller.net/topic/323750 Neues STM32 Tutorial]&lt;br /&gt;
&lt;br /&gt;
[[Category:ARM]]&lt;br /&gt;
[[Category:STM32]]&lt;/div&gt;</summary>
		<author><name>Avrprogger</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Datei:StdPeriphDriver_BasicFramework.zip&amp;diff=81618</id>
		<title>Datei:StdPeriphDriver BasicFramework.zip</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Datei:StdPeriphDriver_BasicFramework.zip&amp;diff=81618"/>
		<updated>2014-02-16T19:08:03Z</updated>

		<summary type="html">&lt;p&gt;Avrprogger: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Avrprogger</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=STM32_-_Einstieg_mit_Em::Blocks&amp;diff=81617</id>
		<title>STM32 - Einstieg mit Em::Blocks</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=STM32_-_Einstieg_mit_Em::Blocks&amp;diff=81617"/>
		<updated>2014-02-16T19:07:38Z</updated>

		<summary type="html">&lt;p&gt;Avrprogger: cvb&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In diesem Tutorial werde ich versuchen, möglichst einfach, die ersten Schritte zur Entwicklung von STM32 Anwenungen mit der Em::Blocks IDE zu erklären. Hier soll nicht so stark auf die einzelnen Peripherie-Module der Controller eingegangen werden, sondern mehr auf die IDE und die verschieden Libraries, wie die CMSIS Library, die DSP-Library, die Standard-Peripheral-Library, die USB-Library und vllt. über Ethernet. Ich denke ein Kapitel zu FreeRTOS wird es auch geben. Auserdem steht im Vordergrund Sachen wie z.B. booten aus dem SRAM, In-Application-Programming, FPU, Core-Coupled-RAM usw. Mal sehn wie weit ich komme ;)&lt;br /&gt;
&lt;br /&gt;
==Die Entwicklungsumgebung==&lt;br /&gt;
===Hardware===&lt;br /&gt;
Zum testen der Anwendungen, benutze ich das STM32F4-Discovery Board, welches einen Debugger, Peripherie und natürlich einen STM32 Controller (STM32F407VGT6) enthält. Deshalb sind alle Beispiele hier für den STM32F407VG Controller ausgelegt, können aber meisten 1:1 auf andere Controller portiert werden. Ich werde auch möglichsts keine STM32F4-Discovery Board spezifischen Libraries verwenden, damit der Portierungs-Vorgang möglichsts einfach bleibt.&lt;br /&gt;
&lt;br /&gt;
===Software===&lt;br /&gt;
In diesem Tutorial verwende ich [http://www.emblocks.org/ Em::Blocks] als IDE. Em::Blocks ist eine kostenlose, uneingeschränkte IDE, die alle STM32 Mikrcontroller unterstützt und sehr einfach zu bedienen ist.&lt;br /&gt;
nach dem Download kann die IDE per Dialog, sehr einfach, installiert werden. Als Compiler beinhaltet Em::Blocks den &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
Die IDE unterstützt zurzeit den ST-Link, den J-Link und es gibt eine Generic-Vorlage, durch welche andere Debugger konfiguriert werden können.&lt;br /&gt;
&lt;br /&gt;
Außerdem muss noch der passende Treiber für den Debugger installiert werden. Verwendet man ein Discovery-Board muss der [http://www.st.com/web/catalog/tools/FM146/CL1984/SC724/SS1677/PF251168 ST-Link/V2]-Treiber heruntergeladen und installiert werden. (Die Installation muss evtl. als Administrator ausgeführt werden, da sonst die Installation unvollständig wird.) Nach der Installation des Treibers kann man den Debugger über die entsprechende USB Schnittstelle an den PC anschließen und es sollte die Meldung von Windows kommen, dass der richtige Treiber gefunden wurde.&lt;br /&gt;
&lt;br /&gt;
===Libraries===&lt;br /&gt;
Zum programmieren benötigt man noch die [http://www.arm.com/products/processors/cortex-m/cortex-microcontroller-software-interface-standard.php CMSIS] und die Standard-Peripheral-Library (z.B. für die F4 Controller [http://www.st.com/stonline/stappl/productcatalog/app?page=partNumberSearchPage&amp;amp;levelid=SS1577&amp;amp;parentid=1743&amp;amp;resourcetype=SW Standard-Peripheral-Library-F4]), die man am besten in einen Ordner (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\STM32&#039;&#039;&#039;&#039;&#039;) entpackt&lt;br /&gt;
&lt;br /&gt;
==Basis-Wissen zur IDE==&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von Dateien zum Projekt===&lt;br /&gt;
Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf &amp;lt;ProjektName&amp;gt; -&amp;gt; Add files...&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Enfernen von Dateien aus dem Projekt===&lt;br /&gt;
Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf die Datei / mehrere Dateien auswählen -&amp;gt; Remove file from project&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
Die Dateien werden lediglich aus dem Projekt entfernt und nicht von der Festplatte gelöscht.&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von Include-Pfaden===&lt;br /&gt;
Sofern die Include-Datei(en) nicht im standard Include-Ordner &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; des Projektes liegen, muss man den Pfad zum Projekt hinzufügen, damit der Compiler die Include-Dateien später auch finden kann. Man geht wie folgt vor: Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; Search Directories -&amp;gt; Add&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von globalen Defines zum Build===&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; #defines&#039;&#039;&#039;&#039;&#039; können globale Defines hinzugefügt werden.&lt;br /&gt;
&lt;br /&gt;
===Compilieren===&lt;br /&gt;
Entweder über das &#039;&#039;&#039;&#039;&#039;Build&#039;&#039;&#039;&#039;&#039; Menü oder über &#039;&#039;&#039;&#039;&#039;F7&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Um eine genau Ausgabe des Compiler-Aufrufes mit allen Argumenten zu bekommen, geht man im &#039;&#039;&#039;&#039;&#039;Settings&#039;&#039;&#039;&#039;&#039; Menü auf &#039;&#039;&#039;&#039;&#039;Tools...&#039;&#039;&#039;&#039;&#039; und dann auf &#039;&#039;&#039;&#039;&#039;Toolchain executables&#039;&#039;&#039;&#039;&#039;. Ganz unten, unter &#039;&#039;&#039;&#039;&#039;Logging&#039;&#039;&#039;&#039;&#039; kann man dann &#039;&#039;&#039;&#039;&#039;Full command line&#039;&#039;&#039;&#039;&#039; auswählen.&lt;br /&gt;
&lt;br /&gt;
====Compiler Optionen====&lt;br /&gt;
=====Optimierung=====&lt;br /&gt;
Standardmäßig verwendet Em::Blocks keine Optimierung. Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; Categories: Optimization&#039;&#039;&#039;&#039;&#039; kann zwischen verschieden Optimierungen ausgewählt werden.&lt;br /&gt;
&lt;br /&gt;
=====Verschiedene C-Standards=====&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; Categories: Language standard&#039;&#039;&#039;&#039;&#039; kann man zwischen verschieden C-Standard auswählen, wie z.B, C99.&lt;br /&gt;
(Mit C99 können auch die Lauf-Variable in der for-Schleife deklariert werden: for(int i;..))&lt;br /&gt;
&lt;br /&gt;
===Debuggen===&lt;br /&gt;
*Als erstes den Debugger starten über das &#039;&#039;&#039;&#039;&#039;Debug&#039;&#039;&#039;&#039;&#039; Menü und &#039;&#039;&#039;&#039;&#039;Start/stop Debug Session&#039;&#039;&#039;&#039;&#039; oder über &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
*Danach läuft die Anwendung auf dem Controller und warten im &#039;&#039;&#039;&#039;&#039;Reset_Handler&#039;&#039;&#039;&#039;&#039; auf Einzelschritt- bzw. Run- Befehle (&#039;&#039;&#039;&#039;&#039;F5, F10, F11&#039;&#039;&#039;&#039;&#039; usw..(siehe &#039;&#039;&#039;&#039;&#039;Debug-Menü&#039;&#039;&#039;&#039;&#039; für alle Möglichkeiten))&lt;br /&gt;
&lt;br /&gt;
*Mit &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039; wird die Debug-Session auch wieder beendet&lt;br /&gt;
&lt;br /&gt;
*Unter &#039;&#039;&#039;&#039;&#039;Debug -&amp;gt; Interfaces -&amp;gt; Target settings&#039;&#039;&#039;&#039;&#039; können Eigenschaften, wie z.B &#039;&#039;&#039;&#039;&#039;Run to main()&#039;&#039;&#039;&#039;&#039; aktiviert werden.&lt;br /&gt;
&lt;br /&gt;
===Projekt als Template abspeichern===&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;File -&amp;gt; Save project as template...&#039;&#039;&#039;&#039;&#039;. Das Template erscheint dann im Projekt-Dialog unter &#039;&#039;&#039;&#039;&#039;User templates&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Das erste Projekt erstellen==&lt;br /&gt;
Hier erkläre ich, wie man am Besten (aus meiner Sicht), ein neues Projekt von Grund auf erstellt, sodass man hinterher, den Controller-Kern über die CMSIS-Library und die Peripherie über die Register steuern kann.&lt;br /&gt;
&lt;br /&gt;
===1. Projekt mit der IDE erstellen===&lt;br /&gt;
Nach der Installation der oben beschriebenen Komponenten erstellt man am besten ein Verzeichnis (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\EmBlocks&#039;&#039;&#039;&#039;&#039;), indem später alle Projekte gespeichert werden. Für Libraries kann man auch noch ein Verzeichnis (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\STM32&#039;&#039;&#039;&#039;&#039;) erstellen, wo alle Libraries gespeichert werden, die man für die Projekt brauchen.&lt;br /&gt;
&lt;br /&gt;
Als nächstes starten man EmBlocks. Bei dem ersten Start öffnet sich ein Fenster, wo verschiedene Compiler angezeigt werden, die Em::Blocks findet. Dort wählt man den &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039; aus und klickt &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039;. Nun sollte sich das Hauptfenster von Em::Blocks öffnen. Über &#039;&#039;&#039;&#039;&#039;Create a new Project&#039;&#039;&#039;&#039;&#039; oder &#039;&#039;&#039;&#039;&#039;File -&amp;gt; New -&amp;gt; Project&#039;&#039;&#039;&#039;&#039; ruft man den Projekt-Dialog auf und kann ein neues Projekt erzeugen.&lt;br /&gt;
&lt;br /&gt;
Auf der Ersten Seite wählen man den &#039;&#039;&#039;&#039;&#039;STmicro-ARM&#039;&#039;&#039;&#039;&#039; Projekt-Typ aus.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_1.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auf der nächsten Seite wird man darauf hingewiesen, dass das der entsprechende Projekt-Typ-Dialog ausgeführt wird. Hier kann man ein Häkchen bei &#039;&#039;&#039;&#039;&#039;Skip this page next time&#039;&#039;&#039;&#039;&#039; setzen und auf &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; klicken.&lt;br /&gt;
&lt;br /&gt;
Im nächsten Schritt wählen man das zuvor erstellt Verzeichnis unter &#039;&#039;&#039;&#039;&#039;Folder to create Project in&#039;&#039;&#039;&#039;&#039; aus, indem später alle Projekt gespeichert werden. Außerdem geben wir dem Projekt einen Namen (z.B. &#039;&#039;&#039;&#039;&#039;FirstProject&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_2.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danach muss man einen Compiler auswählen und bestimmen, welche Projekt-Konfigurationen erszeugt werden sollen. Unter &#039;&#039;&#039;&#039;&#039;Compiler&#039;&#039;&#039;&#039;&#039; wählt man &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039; und man kann das Häkchen bei &#039;&#039;&#039;&#039;&#039;Create &amp;quot;Release&amp;quot; configuration&#039;&#039;&#039;&#039;&#039; entfernen, da diese unnötig ist, die Debug-Konfiguration sollte eig. immer ausreichen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_3.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auf den folgenden Seite wird der Controller ausgewählt. Verwendet man ein STM32F4-Discovery Board müssen folgende Dinge gewählt werden: &#039;&#039;&#039;&#039;&#039;Cortex_M4 (F3xx - F4xx) -&amp;gt; STM32F4xx (Cortex M4 with FPU) -&amp;gt; STM32F407VG&#039;&#039;&#039;&#039;&#039;. Leider sind die Auswahl Möglichkeiten nicht ganz richtig, da auch die F3 Controller einen Cortex M4 Kern und eine FPU haben (Ist aber nicht so wichtig, ist nur eine formale Sache). Außerdem entfernt man das Häkchen bei &#039;&#039;&#039;&#039;&#039;Standard Peripherals Library&#039;&#039;&#039;&#039;&#039; (Wie man die Standard-Peripheral-Library einbindet und verwendet erkläre ich später). Man kann auch das Häkchen bei &#039;&#039;&#039;&#039;&#039;Create hex file for Realease target&#039;&#039;&#039;&#039;&#039; entfernen.&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;Stack Size&#039;&#039;&#039;&#039;&#039; und &#039;&#039;&#039;&#039;&#039;Heap Size&#039;&#039;&#039;&#039;&#039; wird die Größe von Stack und Heap festgelegt. Für eine erste Anwendung kann man die Einstellungen so lassen (Stack-Size: 0x0100 =&amp;gt; 256 Byte Stack und Heap-Size: 0x0000 =&amp;gt; kein Heap). Mit &#039;&#039;&#039;&#039;&#039;Finish&#039;&#039;&#039;&#039;&#039; ist der Projekt Dialog abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_4.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danach sollten sich zwei neue Fenster öffnen, um die Debug-Eigenschaften fest zu legen.&lt;br /&gt;
Verwendet man ein Discovery Board/ST-Link müssen die Einstellungen wie auf dem Bild gewählt werden. Über den Button &#039;&#039;&#039;&#039;&#039;Settings&#039;&#039;&#039;&#039;&#039; öffnet sich das zweite Fenster, falls sich dieses nicht schon von alleine öffnen sollte. Nach den Schließen der Fenster über &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; ist der Projekt Dialog beendet und ein neues Projekt steht zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_5_1.png|Debug Eigenschaften 1. Fenster]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_5_2.png|Debug Eigenschaften 2. Fenster]]&lt;br /&gt;
&lt;br /&gt;
===2. CMSIS-Library und Startup-Code hinzufügen===&lt;br /&gt;
Wenn man sich, nachdem man ein neues Projekt in der IDE erstellt hat, die bereits vorhandenen Dateien im Projekt ansieht, stellt man fest, das bereits ein Ordner &#039;&#039;&#039;&#039;&#039;cmsis&#039;&#039;&#039;&#039;&#039; existiert, der einige wichtige Include-Dateien der CMSIS-Library enthält. Allerdings sind das wirklich nur die wichtigsten Include-Dateien der CMSIS-Library und dazu noch, die aus einer älternen Version. Ich ziehe es deshalb vor die &amp;quot;Mini-CMSIS-Libraray&amp;quot; und die &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c/.h&#039;&#039;&#039;&#039;&#039; Dateien des Projektes durch aktuellere Versionen zu ersetzen. So ist später auch die Integration  von anderen Libraries, wie z.B. der CMSIS-DSP-Libarary einfacher.  &lt;br /&gt;
&lt;br /&gt;
Zunächst gehen man in das Projekt-Verzeichnis und löscht:&lt;br /&gt;
*Den Ordner &#039;&#039;&#039;&#039;&#039;cmsis&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Alle Dateien im Include Verzeichnis &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; im &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner&lt;br /&gt;
&lt;br /&gt;
Außerdem entfernt man auch alle gelöschten Dateien in der IDE aus dem Projekt mit &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Rechts Klick -&amp;gt; Remove file from project&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Es sollte folgende Verzeichnis Struktur überbleiben:&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_6.png|Überbleibende Dateien]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Jetzt müssen die gelöschten Dateien durch die aktuelleren ersetzt werden.&lt;br /&gt;
&lt;br /&gt;
*Dazu kopieren man den gesamten Ordner &#039;&#039;&#039;&#039;&#039;CMSIS&#039;&#039;&#039;&#039;&#039; aus dem CMSIS Download in das Projekt Verzeichnis.&lt;br /&gt;
&lt;br /&gt;
*Aus dem Standard-Peripheral-Library Download kopiert man von &#039;&#039;&#039;&#039;&#039;Libraries\CMSIS\Device\ST\STM32F4xx\Include&#039;&#039;&#039;&#039;&#039; alle Dateien in den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projekt Verzeichnisses&lt;br /&gt;
&lt;br /&gt;
*Aus der Standard-Peripheral-Library kopieren man ebenfalls von &#039;&#039;&#039;&#039;&#039;Libraries\CMSIS\Device\ST\STM32F4xx\Source\Templates&#039;&#039;&#039;&#039;&#039; die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; in den &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner des Projekts&lt;br /&gt;
&lt;br /&gt;
Anschließend müssen die neuen Dateien in der IDE dem Projekt hinzugefügt werden. Dazu benutzt man &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Rechts Klick -&amp;gt; Add files&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
*Aus dem &#039;&#039;&#039;&#039;&#039;CMSIS&#039;&#039;&#039;&#039;&#039; Ordner im Projekt Verzeichnis werden aus den Unterorder &#039;&#039;&#039;&#039;&#039;Include&#039;&#039;&#039;&#039;&#039; folgende Dateien dem Projekt hinzugefügt:&lt;br /&gt;
**arm_common_tables.h&lt;br /&gt;
**arm_const_structs.h&lt;br /&gt;
**arm_math.h&lt;br /&gt;
**core_cm4.h&lt;br /&gt;
**core_cm4_simd.h&lt;br /&gt;
**core_cmFunc.h&lt;br /&gt;
**core_cmInstr.h&lt;br /&gt;
*Alle Dateien aus den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projektes&lt;br /&gt;
*Die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; aus dem &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner&lt;br /&gt;
&lt;br /&gt;
So sollte die Struktur dann aussehen:&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_7.png|Anwenungs-Grundgerüst]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Da einige Dateien der Libraries später bearbeitet werden müssen und Schreibgeschützt sind, weise ich hier schonmal darauf hin, das der Schreibschutz in der IDE über &#039;&#039;&#039;&#039;&#039;Rechts Klick auf die Datei -&amp;gt; Properties -&amp;gt; Häkchen bei &amp;quot;File is read only&amp;quot; entfernen&#039;&#039;&#039;&#039;&#039; entfert werden kann.&lt;br /&gt;
&lt;br /&gt;
Damit die IDE die Header-Dateien der CMSIS Library auch finden kann, weil diese ja nicht im standard Include Ordner &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; liegen, muss unter &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Build Options -&amp;gt; Search Directories&#039;&#039;&#039;&#039;&#039; der Pfad &#039;&#039;&#039;&#039;&#039;CMSIS\Include&#039;&#039;&#039;&#039;&#039; hinzugefügt werden.&lt;br /&gt;
&lt;br /&gt;
Compiliert man jetzt das Projekt mit &#039;&#039;&#039;&#039;&#039;F7&#039;&#039;&#039;&#039;&#039; gibt es ein paar Fehler Meldungen, weil keine Controller-Reihe ausgewählt wurde. Ebenfalls unter &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Build Options -&amp;gt; Compiler Settings -&amp;gt; #defines&#039;&#039;&#039;&#039;&#039; wird der Define &#039;&#039;&#039;&#039;&#039;STM32F40_41xxx&#039;&#039;&#039;&#039;&#039; hinzugefügt.&lt;br /&gt;
&lt;br /&gt;
Beim erneuten Compilieren sollten sich nun keine neuen Fehler ergeben.&lt;br /&gt;
&lt;br /&gt;
===3. Das erste Programm===&lt;br /&gt;
Nachdem ein grundsätzliches &amp;quot;Gerüst&amp;quot; fertig ist, kann man den ersten Code schreiben.&lt;br /&gt;
main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC-&amp;gt;AHB1ENR |= RCC_AHB1ENR_GPIODEN;    //Takt für GPIO aktivieren&lt;br /&gt;
    GPIOD-&amp;gt;MODER |= GPIO_MODER_MODER15_0;   //GPIOD Pin15 als Ausgang&lt;br /&gt;
    GPIOD-&amp;gt;BSRRL |= GPIO_BSRR_BS_15;        //GPIOD Pin15 auf High ziehen&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039; wird dann der Debugger gestartet. Hat der Debugger das Projekt erfolgreich übertragen kann die Ausführung mit &#039;&#039;&#039;&#039;&#039;F5&#039;&#039;&#039;&#039;&#039; begonnen werden.&lt;br /&gt;
&lt;br /&gt;
==Libraries einbinden/verwenden==&lt;br /&gt;
Um Libraries, wie hier im Tutorial, einzubinden, wird ein existierendes Projekt, wie ein im Kapitel [http://www.mikrocontroller.net/articles/STM32_-_Einstieg_mit_Em::Blocks#Das_erste_Projekt_erstellen Das Erste Projekt erstellen] beschrieben wird, vorausgesetzt.&lt;br /&gt;
&lt;br /&gt;
===Einbinden der Standard-Peripheral-Library===&lt;br /&gt;
Um nicht immer die einzelnen Register, wie im ersten &amp;quot;bare-metal&amp;quot; Beispiel, aus dem Reference-Manual zu suchen und zu beschreiben, gibt es von ST die Standard Peripheral Library, die diese Aufgaben übernimmt und mit der sich die &amp;quot;normale/grundlegende&amp;quot; (Alles außer USB und Ethernet) Peripherie recht einfach steuern lässt. Ich kopiere die Standard-Peripheral-Library immer per Hand in das Projekt. Darduch hat man auch gleich die aktuellste Version (in den älteren Version gibt es einige Bugs). &lt;br /&gt;
&lt;br /&gt;
*1. Den Ordner &#039;&#039;&#039;&#039;&#039;Libraries\STM32F4xx_StdPeriph_Driver&#039;&#039;&#039;&#039;&#039; aus dem Standard-Peripheral-Library Download in das Projekt-Verzeichnis kopieren&lt;br /&gt;
*2. Die Datei &#039;&#039;&#039;&#039;&#039;Project\STM32F4xx_StdPeriph_Templates\stm32f4xx_conf.h&#039;&#039;&#039;&#039;&#039; ebenfalls aus dem Standard-Peripheral-Library Download in den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projektes kopieren.&lt;br /&gt;
*3. In der IDE den Include-Path &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\inc&#039;&#039;&#039;&#039;&#039; hinzufügen&lt;br /&gt;
*4. Und das/den Define &#039;&#039;&#039;&#039;&#039;USE_STDPERIPH_DRIVER&#039;&#039;&#039;&#039;&#039; hinzufügen&lt;br /&gt;
*4. Source- und Include-Dateien zum Projekt hinzufügen&lt;br /&gt;
**Achtung: Es dürfen nur die Dateien hinzugefügt werden, für die der Controller auch die entsprechende Peripherie bereit stellt. Diese Dateien dürfen nicht beim STM32F4-Discovery/STM32F407VG hinzugefügt werden.&lt;br /&gt;
***stm32f4xx_dma2d.c/.h&lt;br /&gt;
***stm32f4xx_fmc.c/.h&lt;br /&gt;
***stm32f4xx_ltdc.c/.h&lt;br /&gt;
***stm32f4xx_sai.c/.h&lt;br /&gt;
&lt;br /&gt;
Daraus resultiert folgende Struktur:&lt;br /&gt;
&lt;br /&gt;
[[Datei:stdperiphlib_2.png|Header-Struktur]] [[Datei:stdperiphlib_1.png|Source-Struktur]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Anschließen kann die Standard-Peripheral-Library benutz werden.&lt;br /&gt;
main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);&lt;br /&gt;
&lt;br /&gt;
    GPIO_InitTypeDef GPIOD_InitStructure;&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Mode = GPIO_Mode_OUT;     //Als Ausgang&lt;br /&gt;
    GPIOD_InitStructure.GPIO_OType = GPIO_OType_PP;    //Push-Pull Betrieb&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Pin = GPIO_Pin_15;        //Pin 15 (STM32F4-Discovery: Blaue LED)&lt;br /&gt;
    GPIOD_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;  //Kein Pull-Up oder Pull-Down Widerstand aktiviert&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Speed = GPIO_Speed_25MHz; //25MHz Update-Rate&lt;br /&gt;
    GPIO_Init(GPIOD, &amp;amp;GPIOD_InitStructure);&lt;br /&gt;
&lt;br /&gt;
    GPIO_SetBits(GPIOD, GPIO_Pin_15);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hier ist noch ein &amp;quot;BasicFramework&amp;quot;, dass die komplette CMSIS- und Standard-Peripheral-Library enthält und kann Quasi als Basis für alle Projekte verwendet werden. Allerdings ist das Framework primär auf die STM32F405/7 und STM32F415/7 ausgelegt. Die neueren STM32F401, STM32F42X und STM32F43X  haben noch etwas andere Peripherie, dass Framework müsste dann entsprechend angepasst werden. Download: [[Datei:StdPeriphDriver_BasicFramework.zip]]&lt;br /&gt;
&lt;br /&gt;
===Einbinden der DSP-Library===&lt;br /&gt;
STM32F3 / STM32F4 Microcontroller haben neben der FPU noch einen Digital-Signal-Processor (DSP). Die DSP dient hauptsächlich dazu, viele Daten schnell zu verarbeiten (z.B. Video- oder Audiosignal). Der CMSIS-Download beinhaltet dazu neben der eigentlichen CMSIS-Library auch noch eine DSP-Library. Diese Library stellt sowohl einfache, mathematische Funktionen wie addieren, multiplizieren usw. als auch komplexe Funktionen, wie z.B  einen IIR-Filter, zur Verfügung. Die DSP-Library ist weiter aufgeteilt in kleinere Module, wie z.B. BasicMathFunctions, FilteringFunctions usw. (siehe &#039;&#039;&#039;&#039;&#039;CMSIS\DSP-Library\Source&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
*1. Source-Dateien des benötigten Moduls zum Projekt hinzufügen. (&#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Add files...&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
*2. &#039;&#039;&#039;&#039;&#039;arm_math.h&#039;&#039;&#039;&#039;&#039; in der &#039;&#039;&#039;&#039;&#039;main.c&#039;&#039;&#039;&#039;&#039; einbinden&lt;br /&gt;
*3. Damit die Warnung &amp;quot;Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)&amp;quot; verschwindet, muss der Define &#039;&#039;&#039;&#039;&#039;__FPU_PRESENT&#039;&#039;&#039;&#039;&#039; hinzugefügt werden. (Keine Ahnung, wieso es die Warnung gibt)&lt;br /&gt;
 &lt;br /&gt;
Jetzt kann die DSP-Library verwedet werden. Das Beispiel multipliziert zwei Buffer miteinander. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
#include &amp;quot;arm_math.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    float32_t x[1024];&lt;br /&gt;
    float32_t y[1024];&lt;br /&gt;
    float32_t z[1024];&lt;br /&gt;
&lt;br /&gt;
    for(uint16_t i = 0; i &amp;lt; 1024; i++)&lt;br /&gt;
    {&lt;br /&gt;
        x[i] = i;&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for(uint16_t i = 0; i &amp;lt; 1024; i++)&lt;br /&gt;
    {&lt;br /&gt;
        y[i] = PI;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    arm_mult_f32(x, y, z, 1024);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Startup-Code, Linker-Script, Takt, FPU usw.==&lt;br /&gt;
===Startup-Code===&lt;br /&gt;
Em::Blocks fügt standardmäßig einen Startup-Code mit in das Projekt ein. Die wichtigsten Dinge die darin erledigt werden sind folgende:&lt;br /&gt;
&lt;br /&gt;
*Stack und Heap wird angelgt&lt;br /&gt;
*Die Vector-Table wird angelegt&lt;br /&gt;
*Ein Default Reset-Handler wird implementiert, dieser erledigt folgende aufgaben:&lt;br /&gt;
**Kopieren der definierten Daten aus dem Flash in den SRAM&lt;br /&gt;
**&#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; wird aufgerufen, wenn &#039;&#039;&#039;&#039;&#039;__NO_SYSTEM_INIT&#039;&#039;&#039;&#039;&#039; nicht definiert ist&lt;br /&gt;
**Sprung in die &#039;&#039;&#039;&#039;&#039;main()&#039;&#039;&#039;&#039;&#039; Funktion&lt;br /&gt;
*Allen anderen Interrupt-Handler wird eine Default-Funktion &#039;&#039;&#039;&#039;&#039;def_irq_handler&#039;&#039;&#039;&#039;&#039; mit einer &#039;&#039;&#039;&#039;&#039;while(1)&#039;&#039;&#039;&#039;&#039;-Schleife zugewiesen, falls kein anderer Interrupt-Handler existiert.&lt;br /&gt;
&lt;br /&gt;
Normalerweise muss am Startup-Code nichts verändert werden.&lt;br /&gt;
&lt;br /&gt;
===Linker-Script===&lt;br /&gt;
Em::Blocks stellt zwei fertige Linker-Scripts bereit, eins für die Ausführung des Programmes aus dem Flash (&#039;&#039;&#039;&#039;&#039;*_flash.ld&#039;&#039;&#039;&#039;&#039;), das andere für die Ausführung aus dem SRAM (&#039;&#039;&#039;&#039;&#039;*_sram.ld&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Normalerweise muss auch hier nichts geändert werden, es sei den Daten sollen in bestimmten Adressbereichen abgelegt werden (z.B. im Core-Coupled RAM), was ich später noch zum Tutorial hinzufüge.&lt;br /&gt;
&lt;br /&gt;
===Der Takt===&lt;br /&gt;
Jeder Controller oder Prozessor braucht einen Takt, indem er die einzelnen Maschinen-Befehle abarbeiten kann.&lt;br /&gt;
Bei den STM32 Mikrocontrollern kann dieser Takt aus verschiedenen Quellen kommen:&lt;br /&gt;
&lt;br /&gt;
1. High Speed Internal Oszillator (HSI)&lt;br /&gt;
&lt;br /&gt;
2. High Speed External Oszillator (HSE)&lt;br /&gt;
&lt;br /&gt;
3. Low Speed Internal Oszillator (LSI)&lt;br /&gt;
&lt;br /&gt;
4. Low Speed External Oszillator (LSE)&lt;br /&gt;
&lt;br /&gt;
5. Phase-Locked Loop (PLL) (generiert den Takt aus den ersten vier Taktquellen durch Teiler und Faktoren)&lt;br /&gt;
&lt;br /&gt;
Nach einem Reset wird der Controller aus der HSI Taktquelle versorgt (16MHz beim STM32F407VG). Um die voll Performance des Controllers zu erreichen muss die PLL verwendet werden, welche den Takt durch geschickte Teiler und Faktoren vervielfältigt, sodass am Ende der Controller mit der maximalen Taktfrequenz läuft. Die notwendige Initialisierung der PLL findet in der Funktion &#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; statt. Die PLL erzeugt zunächst einen Basistakt:&lt;br /&gt;
&lt;br /&gt;
PLL_VCO = (F_HSE / PLL_M) * PLL_N&lt;br /&gt;
&lt;br /&gt;
Aus diesem Takt wird dann der Takt für den Controller-Kern abgeleitet:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = PLL_VCO / PLL_P&lt;br /&gt;
&lt;br /&gt;
Und der Takt für SDIO / USB / RNG (48MHz):&lt;br /&gt;
&lt;br /&gt;
48MHz = PLL_VCO / PLL_Q&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Durch weiter Teiler werden, die Takte für die einzelnen Busse erzeugt, da diese nicht alle beliebig schnell betrieben werden dürfen.&lt;br /&gt;
&lt;br /&gt;
Genaue Angaben findet man zu dem jeweiligen Clock-System des Controllers im Reference Manual.&lt;br /&gt;
&lt;br /&gt;
Ein Blick in den &amp;quot;Kommentar-Header&amp;quot; verrät, dass von einem externen (HSE) Oszillator von 25MHz ausgegangen wird, der die PLL versorgen soll.&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((25MHz / PLL_M(25)) * PLL_N(336)) / PLL_P(2) = 168MHz&lt;br /&gt;
&lt;br /&gt;
Allerdings stimmt diese Rechnung natürlich nur, wenn wirklich ein 25MHz Quarz am Controller angeschlossen ist. Auf dem STM32F4-Discovery Board befindet sich aber nur ein 8MHz Quarz. Demnach gilt:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((8MHz / PLL_M(25)) * PLL_N(336)) / PLL_P(2) = 53.76MHz&lt;br /&gt;
&lt;br /&gt;
Der Controller läuft also nur mit 53.76MHz, wenn wie ober beschrieben ein Projekt erstellt wird. Allerdings kann dieses Problem durch ändern von den betroffen Defines behoben werden:&lt;br /&gt;
 &lt;br /&gt;
*Dazu geht man in die &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; Datei und passt zur Vollständigkeit erstmal die zum Controller passende Tabelle im &amp;quot;Kommentar-Header&amp;quot; an (Z.57f):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      HSE Frequency(Hz)                      | 8000000&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      PLL_M                                  | 8&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Danach passt man den PPL_M Define (Z.254) an:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/************************* PLL Parameters *************************************/&lt;br /&gt;
/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */&lt;br /&gt;
#define PLL_M      8&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Außerdem muss man den HSE_VALUE Define in der &#039;&#039;&#039;&#039;&#039;inc/stm32f4xx.h&#039;&#039;&#039;&#039;&#039; angepasst werden (Z.122):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#if !defined  (HSE_VALUE)&lt;br /&gt;
  #define HSE_VALUE    ((uint32_t)8000000) /*!&amp;lt; Value of the External oscillator in Hz */&lt;br /&gt;
&lt;br /&gt;
#endif /* HSE_VALUE */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine neue Berechnung zeigt:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((8MHz / PLL_M(8)) * PLL_N(336)) / PLL_P(2) = 168MHz&lt;br /&gt;
&lt;br /&gt;
Jetzt läuft der Controller mit maximaler Geschwindigkeit.&lt;br /&gt;
&lt;br /&gt;
Die Theorie wird durch folgendes Programm verifiziert. Der geviertelte System-Takt SYSCLK wir am Pin PC9 ausgegeben. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);&lt;br /&gt;
&lt;br /&gt;
    GPIO_InitTypeDef GPIOC_InitStructure;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Mode = GPIO_Mode_AF;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_OType = GPIO_OType_PP;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Pin = GPIO_Pin_9;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;&lt;br /&gt;
    GPIO_Init(GPIOC, &amp;amp;GPIOC_InitStructure);&lt;br /&gt;
&lt;br /&gt;
    RCC_MCO2Config(RCC_MCO2Source_SYSCLK, RCC_MCO2Div_4);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Die FPU===&lt;br /&gt;
====Allgemeines====&lt;br /&gt;
STM32F3 und STM32F4 Controller haben eine FPU.&lt;br /&gt;
Damit die FPU richtig verwendet wird, müssen normalerweise zwei Bedingungen erfüllt sein:&lt;br /&gt;
&lt;br /&gt;
1. Der Controller muss die FPU Hardware-seitig aktivieren&lt;br /&gt;
&lt;br /&gt;
2. Damit die FPU auch was zu tuen bekommt, müssen vom Compiler FPU-Instructions erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
Die Em::Blocks IDE verwendet standardmäßig die FPU, wenn eine Vorhanden ist. Hier wird die FPU Hardware-seitig aktiviert (&#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; Z.341):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* FPU settings ------------------------------------------------------------*/&lt;br /&gt;
  #if (__FPU_PRESENT == 1) &amp;amp;&amp;amp; (__FPU_USED == 1)&lt;br /&gt;
    SCB-&amp;gt;CPACR |= ((3UL &amp;lt;&amp;lt; 10*2)|(3UL &amp;lt;&amp;lt; 11*2));  /* set CP10 and CP11 Full Access */&lt;br /&gt;
  #endif&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
__FPU_PRESENT wird in der &#039;&#039;&#039;&#039;&#039;stm32f4xx.h&#039;&#039;&#039;&#039;&#039; definiert.&lt;br /&gt;
__FPU_USED wird von der IDE übernommen (siehe Build-Log): &#039;&#039;&#039;&#039;&#039;-D__FPU_USED&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Außerdem wird der Compiler von der IDE standardmäßig mit dem Argument &#039;&#039;&#039;&#039;&#039;-mfloat-abi=hard&#039;&#039;&#039;&#039;&#039; aufgerufen, wodurch FPU-Instructions erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
====FPU abschalten====&lt;br /&gt;
Um die FPU ab zu schalten (Mir würde jetzt nur Strom sparen als Grund einfallen) geht man wie folgt vor:&lt;br /&gt;
&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; Device -&amp;gt; Policy&#039;&#039;&#039;&#039;&#039; wählt man &#039;&#039;&#039;&#039;&#039;Use target settings&#039;&#039;&#039;&#039;&#039; und über nimmt die Einstellungen, die vorher dort eingetragen waren, allerdings lässt man das Feld &#039;&#039;&#039;&#039;&#039;FP-hardware&#039;&#039;&#039;&#039;&#039; frei.&lt;br /&gt;
&lt;br /&gt;
[[Datei:fpu_1.png|FPU Abschalten Schritt 1]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;Compiler Settings -&amp;gt; Policy&#039;&#039;&#039;&#039;&#039; wählt man dann &#039;&#039;&#039;&#039;&#039;Use target options only&#039;&#039;&#039;&#039;&#039;. Dann kann man unter &#039;&#039;&#039;&#039;&#039;Categories&#039;&#039;&#039;&#039;&#039; die Option &#039;&#039;&#039;&#039;&#039;ARM FPU architecture&#039;&#039;&#039;&#039;&#039; auswählen. Dort stehen dann drei Möglichkeiten für die FPU zur Verfügung:&lt;br /&gt;
&lt;br /&gt;
1. Software-FPU-Library für Gleitkomma-Berechnung verwenden - Keine FPU-Instructions werden generiert (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=soft&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
2. Eine Mischung aus Software- und Hardware-FPU wird verwendet (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=softfp&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
3. Hardware-FPU wird für Gleitkomma-Berechnungen verwendet (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=hard&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
[[Datei:fpu_2.png|FPU Abschalten Schritt 2]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Um die FPU ab zu schalten wählt man natürlich die erste Möglichkeit.&lt;br /&gt;
Bei der 2. und 3. Möglichkeit fügt die IDE auch den Define &#039;&#039;&#039;&#039;&#039;__FPU_USED&#039;&#039;&#039;&#039;&#039; hinzu. Bei Der ersten Möglichkeit nicht. Der Code muss also nicht verändert / auskommentiert werden.&lt;br /&gt;
&lt;br /&gt;
Um die FPU wieder zu aktivieren müssen alle Schritte wieder rückgängig gemacht werden.&lt;br /&gt;
&lt;br /&gt;
Am besten ist es einfach mal alle Möglichkeiten im Einzelschritt durch zu probieren. Dann stellt man schnell fest, ob die FPU aktiviert wir oder nicht. Ein Blick in den erweiterten &#039;&#039;&#039;&#039;&#039;Build-Log&#039;&#039;&#039;&#039;&#039; gibt auch schnell Aufschluss darüber, wie der Compiler aufgerufen wird (siehe Kapitel [http://www.mikrocontroller.net/articles/STM32_-_Einstieg_mit_Em::Blocks#Compilieren Compilieren]).&lt;br /&gt;
&lt;br /&gt;
====Test Programm für die FPU====&lt;br /&gt;
Hier ein kleines Testprogramm, dass misst wie viele Taktzyklen für eine Gleitkomma-Multiplikation gebraucht werden. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define CORE_SysTickEn()    (*((u32*)0xE0001000)) = 0x40000001&lt;br /&gt;
#define CORE_SysTickDis()   (*((u32*)0xE0001000)) = 0x40000000&lt;br /&gt;
#define CORE_GetSysTick()   (*((u32*)0xE0001004))&lt;br /&gt;
&lt;br /&gt;
uint32_t t1, t2, dt;&lt;br /&gt;
float x, y, z;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    x = 53.64f;&lt;br /&gt;
    y = 0.27f;&lt;br /&gt;
&lt;br /&gt;
    CORE_SysTickEn();&lt;br /&gt;
    t1 = CORE_GetSysTick();&lt;br /&gt;
&lt;br /&gt;
    z = x * y;&lt;br /&gt;
&lt;br /&gt;
    t2 = CORE_GetSysTick();&lt;br /&gt;
    CORE_SysTickDis();&lt;br /&gt;
&lt;br /&gt;
    dt = (t2 - t1) - 9; //9 Takt-Zyklen werden für die Messung gebraucht &lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Booten aus dem SRAM==&lt;br /&gt;
STM32 Controller haben die Möglichkeit Code aus dem Flash als auch aus dem SRAM auszuführen. Um eine Anwenung per Debugger in des SRAM zu laden sind nur wenige Schritte erforderlich:&lt;br /&gt;
&lt;br /&gt;
*Um das Linkerscript für den SRAM zu verwenden geht man zu: &#039;&#039;&#039;&#039;&#039;Build options... -&amp;gt; Device&#039;&#039;&#039;&#039;&#039; dort wählt man unter &#039;&#039;&#039;&#039;&#039;Policy&#039;&#039;&#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;Use target settings&#039;&#039;&#039;&#039;&#039; aus und übernimmt die vorherigen Einstellungen, nur unter &#039;&#039;&#039;&#039;&#039;Linker script*&#039;&#039;&#039;&#039;&#039; gibt man &#039;&#039;&#039;&#039;&#039;.\stm32f407vg_sram.ld&#039;&#039;&#039;&#039;&#039; an&lt;br /&gt;
&lt;br /&gt;
*Dann muss man noch unter &#039;&#039;&#039;&#039;&#039;Debug -&amp;gt; Interfaces -&amp;gt; Settings&#039;&#039;&#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;Vector table start&#039;&#039;&#039;&#039;&#039; auf 0x20000000 ändern und &#039;&#039;&#039;&#039;&#039;Execute from RAM&#039;&#039;&#039;&#039;&#039; auswählen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:bootsram_1.png Booten aus dem SRAM]] [[Datei:bootsram_2.png Booten aus dem SRAM]]&lt;br /&gt;
&lt;br /&gt;
Anschließend kann man die Anwendung ganz normal debuggen. Nach einem Reset muss die Anwenung erneut mit dem Debugger gestartet werden.&lt;br /&gt;
&lt;br /&gt;
=Fortsetzung folgt..=&lt;br /&gt;
Kritik, Wünsche usw. sind gerne erwünscht, am besten hier in den Thread posten: [http://www.mikrocontroller.net/topic/323750 Neues STM32 Tutorial]&lt;br /&gt;
&lt;br /&gt;
[[Category:ARM]]&lt;br /&gt;
[[Category:STM32]]&lt;/div&gt;</summary>
		<author><name>Avrprogger</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Datei:Bootsram_2.png_Booten_aus_dem_SRAM&amp;diff=81572</id>
		<title>Datei:Bootsram 2.png Booten aus dem SRAM</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Datei:Bootsram_2.png_Booten_aus_dem_SRAM&amp;diff=81572"/>
		<updated>2014-02-13T14:27:40Z</updated>

		<summary type="html">&lt;p&gt;Avrprogger: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Avrprogger</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Datei:Bootsram_1.png_Booten_aus_dem_SRAM&amp;diff=81571</id>
		<title>Datei:Bootsram 1.png Booten aus dem SRAM</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Datei:Bootsram_1.png_Booten_aus_dem_SRAM&amp;diff=81571"/>
		<updated>2014-02-13T14:27:25Z</updated>

		<summary type="html">&lt;p&gt;Avrprogger: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Avrprogger</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=STM32_-_Einstieg_mit_Em::Blocks&amp;diff=81570</id>
		<title>STM32 - Einstieg mit Em::Blocks</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=STM32_-_Einstieg_mit_Em::Blocks&amp;diff=81570"/>
		<updated>2014-02-13T14:27:05Z</updated>

		<summary type="html">&lt;p&gt;Avrprogger: fgh&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In diesem Tutorial werde ich versuchen, möglichst einfach, die ersten Schritte zur Entwicklung von STM32 Anwenungen mit der Em::Blocks IDE zu erklären. Hier soll nicht so stark auf die einzelnen Peripherie-Module der Controller eingegangen werden, sondern mehr auf die IDE und die verschieden Libraries, wie die CMSIS Library, die DSP-Library, die Standard-Peripheral-Library, die USB-Library und vllt. über Ethernet. Ich denke ein Kapitel zu FreeRTOS wird es auch geben. Auserdem steht im Vordergrund Sachen wie z.B. booten aus dem SRAM, In-Application-Programming, FPU, Core-Coupled-RAM usw. Mal sehn wie weit ich komme ;)&lt;br /&gt;
&lt;br /&gt;
==Die Entwicklungsumgebung==&lt;br /&gt;
===Hardware===&lt;br /&gt;
Zum testen der Anwendungen, benutze ich das STM32F4-Discovery Board, welches einen Debugger, Peripherie und natürlich einen STM32 Controller (STM32F407VGT6) enthält. Deshalb sind alle Beispiele hier für den STM32F407VG Controller ausgelegt, können aber meisten 1:1 auf andere Controller portiert werden. Ich werde auch möglichsts keine STM32F4-Discovery Board spezifischen Libraries verwenden, damit der Portierungs-Vorgang möglichsts einfach bleibt.&lt;br /&gt;
&lt;br /&gt;
===Software===&lt;br /&gt;
In diesem Tutorial verwende ich [http://www.emblocks.org/ Em::Blocks] als IDE. Em::Blocks ist eine kostenlose, uneingeschränkte IDE, die alle STM32 Mikrcontroller unterstützt und sehr einfach zu bedienen ist.&lt;br /&gt;
nach dem Download kann die IDE per Dialog, sehr einfach, installiert werden. Als Compiler beinhaltet Em::Blocks den &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
Die IDE unterstützt zurzeit den ST-Link, den J-Link und es gibt eine Generic-Vorlage, durch welche andere Debugger konfiguriert werden können.&lt;br /&gt;
&lt;br /&gt;
Außerdem muss noch der passende Treiber für den Debugger installiert werden. Verwendet man ein Discovery-Board muss der [http://www.st.com/web/catalog/tools/FM146/CL1984/SC724/SS1677/PF251168 ST-Link/V2]-Treiber heruntergeladen und installiert werden. (Die Installation muss evtl. als Administrator ausgeführt werden, da sonst die Installation unvollständig wird.) Nach der Installation des Treibers kann man den Debugger über die entsprechende USB Schnittstelle an den PC anschließen und es sollte die Meldung von Windows kommen, dass der richtige Treiber gefunden wurde.&lt;br /&gt;
&lt;br /&gt;
===Libraries===&lt;br /&gt;
Zum programmieren benötigt man noch die [http://www.arm.com/products/processors/cortex-m/cortex-microcontroller-software-interface-standard.php CMSIS] und die Standard-Peripheral-Library (z.B. für die F4 Controller [http://www.st.com/stonline/stappl/productcatalog/app?page=partNumberSearchPage&amp;amp;levelid=SS1577&amp;amp;parentid=1743&amp;amp;resourcetype=SW Standard-Peripheral-Library-F4]), die man am besten in einen Ordner (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\STM32&#039;&#039;&#039;&#039;&#039;) entpackt&lt;br /&gt;
&lt;br /&gt;
==Basis-Wissen zur IDE==&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von Dateien zum Projekt===&lt;br /&gt;
Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf &amp;lt;ProjektName&amp;gt; -&amp;gt; Add files...&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Enfernen von Dateien aus dem Projekt===&lt;br /&gt;
Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf die Datei / mehrere Dateien auswählen -&amp;gt; Remove file from project&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
Die Dateien werden lediglich aus dem Projekt entfernt und nicht von der Festplatte gelöscht.&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von Include-Pfaden===&lt;br /&gt;
Sofern die Include-Datei(en) nicht im standard Include-Ordner &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; des Projektes liegen, muss man den Pfad zum Projekt hinzufügen, damit der Compiler die Include-Dateien später auch finden kann. Man geht wie folgt vor: Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; Search Directories -&amp;gt; Add&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von globalen Defines zum Build===&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; #defines&#039;&#039;&#039;&#039;&#039; können globale Defines hinzugefügt werden.&lt;br /&gt;
&lt;br /&gt;
===Compilieren===&lt;br /&gt;
Entweder über das &#039;&#039;&#039;&#039;&#039;Build&#039;&#039;&#039;&#039;&#039; Menü oder über &#039;&#039;&#039;&#039;&#039;F7&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Um eine genau Ausgabe des Compiler-Aufrufes mit allen Argumenten zu bekommen, geht man im &#039;&#039;&#039;&#039;&#039;Settings&#039;&#039;&#039;&#039;&#039; Menü auf &#039;&#039;&#039;&#039;&#039;Tools...&#039;&#039;&#039;&#039;&#039; und dann auf &#039;&#039;&#039;&#039;&#039;Toolchain executables&#039;&#039;&#039;&#039;&#039;. Ganz unten, unter &#039;&#039;&#039;&#039;&#039;Logging&#039;&#039;&#039;&#039;&#039; kann man dann &#039;&#039;&#039;&#039;&#039;Full command line&#039;&#039;&#039;&#039;&#039; auswählen.&lt;br /&gt;
&lt;br /&gt;
====Compiler Optionen====&lt;br /&gt;
=====Optimierung=====&lt;br /&gt;
Standardmäßig verwendet Em::Blocks keine Optimierung. Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; Categories: Optimization&#039;&#039;&#039;&#039;&#039; kann zwischen verschieden Optimierungen ausgewählt werden.&lt;br /&gt;
&lt;br /&gt;
=====Verschiedene C-Standards=====&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; Categories: Language standard&#039;&#039;&#039;&#039;&#039; kann man zwischen verschieden C-Standard auswählen, wie z.B, C99.&lt;br /&gt;
(Mit C99 können auch die Lauf-Variable in der for-Schleife deklariert werden: for(int i;..))&lt;br /&gt;
&lt;br /&gt;
===Debuggen===&lt;br /&gt;
*Als erstes den Debugger starten über das &#039;&#039;&#039;&#039;&#039;Debug&#039;&#039;&#039;&#039;&#039; Menü und &#039;&#039;&#039;&#039;&#039;Start/stop Debug Session&#039;&#039;&#039;&#039;&#039; oder über &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
*Danach läuft die Anwendung auf dem Controller und warten im &#039;&#039;&#039;&#039;&#039;Reset_Handler&#039;&#039;&#039;&#039;&#039; auf Einzelschritt- bzw. Run- Befehle (&#039;&#039;&#039;&#039;&#039;F5, F10, F11&#039;&#039;&#039;&#039;&#039; usw..(siehe &#039;&#039;&#039;&#039;&#039;Debug-Menü&#039;&#039;&#039;&#039;&#039; für alle Möglichkeiten))&lt;br /&gt;
&lt;br /&gt;
*Mit &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039; wird die Debug-Session auch wieder beendet&lt;br /&gt;
&lt;br /&gt;
*Unter &#039;&#039;&#039;&#039;&#039;Debug -&amp;gt; Interfaces -&amp;gt; Target settings&#039;&#039;&#039;&#039;&#039; können Eigenschaften, wie z.B &#039;&#039;&#039;&#039;&#039;Run to main()&#039;&#039;&#039;&#039;&#039; aktiviert werden.&lt;br /&gt;
&lt;br /&gt;
===Projekt als Template abspeichern===&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;File -&amp;gt; Save project as template...&#039;&#039;&#039;&#039;&#039;. Das Template erscheint dann im Projekt-Dialog unter &#039;&#039;&#039;&#039;&#039;User templates&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Das erste Projekt erstellen==&lt;br /&gt;
Hier erkläre ich, wie man am Besten (aus meiner Sicht), ein neues Projekt von Grund auf erstellt, sodass man hinterher, den Controller-Kern über die CMSIS-Library und die Peripherie über die Register steuern kann.&lt;br /&gt;
&lt;br /&gt;
===1. Projekt mit der IDE erstellen===&lt;br /&gt;
Nach der Installation der oben beschriebenen Komponenten erstellt man am besten ein Verzeichnis (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\EmBlocks&#039;&#039;&#039;&#039;&#039;), indem später alle Projekte gespeichert werden. Für Libraries kann man auch noch ein Verzeichnis (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\STM32&#039;&#039;&#039;&#039;&#039;) erstellen, wo alle Libraries gespeichert werden, die man für die Projekt brauchen.&lt;br /&gt;
&lt;br /&gt;
Als nächstes starten man EmBlocks. Bei dem ersten Start öffnet sich ein Fenster, wo verschiedene Compiler angezeigt werden, die Em::Blocks findet. Dort wählt man den &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039; aus und klickt &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039;. Nun sollte sich das Hauptfenster von Em::Blocks öffnen. Über &#039;&#039;&#039;&#039;&#039;Create a new Project&#039;&#039;&#039;&#039;&#039; oder &#039;&#039;&#039;&#039;&#039;File -&amp;gt; New -&amp;gt; Project&#039;&#039;&#039;&#039;&#039; ruft man den Projekt-Dialog auf und kann ein neues Projekt erzeugen.&lt;br /&gt;
&lt;br /&gt;
Auf der Ersten Seite wählen man den &#039;&#039;&#039;&#039;&#039;STmicro-ARM&#039;&#039;&#039;&#039;&#039; Projekt-Typ aus.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_1.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auf der nächsten Seite wird man darauf hingewiesen, dass das der entsprechende Projekt-Typ-Dialog ausgeführt wird. Hier kann man ein Häkchen bei &#039;&#039;&#039;&#039;&#039;Skip this page next time&#039;&#039;&#039;&#039;&#039; setzen und auf &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; klicken.&lt;br /&gt;
&lt;br /&gt;
Im nächsten Schritt wählen man das zuvor erstellt Verzeichnis unter &#039;&#039;&#039;&#039;&#039;Folder to create Project in&#039;&#039;&#039;&#039;&#039; aus, indem später alle Projekt gespeichert werden. Außerdem geben wir dem Projekt einen Namen (z.B. &#039;&#039;&#039;&#039;&#039;FirstProject&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_2.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danach muss man einen Compiler auswählen und bestimmen, welche Projekt-Konfigurationen erszeugt werden sollen. Unter &#039;&#039;&#039;&#039;&#039;Compiler&#039;&#039;&#039;&#039;&#039; wählt man &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039; und man kann das Häkchen bei &#039;&#039;&#039;&#039;&#039;Create &amp;quot;Release&amp;quot; configuration&#039;&#039;&#039;&#039;&#039; entfernen, da diese unnötig ist, die Debug-Konfiguration sollte eig. immer ausreichen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_3.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auf den folgenden Seite wird der Controller ausgewählt. Verwendet man ein STM32F4-Discovery Board müssen folgende Dinge gewählt werden: &#039;&#039;&#039;&#039;&#039;Cortex_M4 (F3xx - F4xx) -&amp;gt; STM32F4xx (Cortex M4 with FPU) -&amp;gt; STM32F407VG&#039;&#039;&#039;&#039;&#039;. Leider sind die Auswahl Möglichkeiten nicht ganz richtig, da auch die F3 Controller einen Cortex M4 Kern und eine FPU haben (Ist aber nicht so wichtig, ist nur eine formale Sache). Außerdem entfernt man das Häkchen bei &#039;&#039;&#039;&#039;&#039;Standard Peripherals Library&#039;&#039;&#039;&#039;&#039; (Wie man die Standard-Peripheral-Library einbindet und verwendet erkläre ich später). Man kann auch das Häkchen bei &#039;&#039;&#039;&#039;&#039;Create hex file for Realease target&#039;&#039;&#039;&#039;&#039; entfernen.&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;Stack Size&#039;&#039;&#039;&#039;&#039; und &#039;&#039;&#039;&#039;&#039;Heap Size&#039;&#039;&#039;&#039;&#039; wird die Größe von Stack und Heap festgelegt. Für eine erste Anwendung kann man die Einstellungen so lassen (Stack-Size: 0x0100 =&amp;gt; 256 Byte Stack und Heap-Size: 0x0000 =&amp;gt; kein Heap). Mit &#039;&#039;&#039;&#039;&#039;Finish&#039;&#039;&#039;&#039;&#039; ist der Projekt Dialog abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_4.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danach sollten sich zwei neue Fenster öffnen, um die Debug-Eigenschaften fest zu legen.&lt;br /&gt;
Verwendet man ein Discovery Board/ST-Link müssen die Einstellungen wie auf dem Bild gewählt werden. Über den Button &#039;&#039;&#039;&#039;&#039;Settings&#039;&#039;&#039;&#039;&#039; öffnet sich das zweite Fenster, falls sich dieses nicht schon von alleine öffnen sollte. Nach den Schließen der Fenster über &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; ist der Projekt Dialog beendet und ein neues Projekt steht zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_5_1.png|Debug Eigenschaften 1. Fenster]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_5_2.png|Debug Eigenschaften 2. Fenster]]&lt;br /&gt;
&lt;br /&gt;
===2. CMSIS-Library und Startup-Code hinzufügen===&lt;br /&gt;
Wenn man sich, nachdem man ein neues Projekt in der IDE erstellt hat, die bereits vorhandenen Dateien im Projekt ansieht, stellt man fest, das bereits ein Ordner &#039;&#039;&#039;&#039;&#039;cmsis&#039;&#039;&#039;&#039;&#039; existiert, der einige wichtige Include-Dateien der CMSIS-Library enthält. Allerdings sind das wirklich nur die wichtigsten Include-Dateien der CMSIS-Library und dazu noch, die aus einer älternen Version. Ich ziehe es deshalb vor die &amp;quot;Mini-CMSIS-Libraray&amp;quot; und die &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c/.h&#039;&#039;&#039;&#039;&#039; Dateien des Projektes durch aktuellere Versionen zu ersetzen. So ist später auch die Integration  von anderen Libraries, wie z.B. der CMSIS-DSP-Libarary einfacher.  &lt;br /&gt;
&lt;br /&gt;
Zunächst gehen man in das Projekt-Verzeichnis und löscht:&lt;br /&gt;
*Den Ordner &#039;&#039;&#039;&#039;&#039;cmsis&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Alle Dateien im Include Verzeichnis &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; im &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner&lt;br /&gt;
&lt;br /&gt;
Außerdem entfernt man auch alle gelöschten Dateien in der IDE aus dem Projekt mit &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Rechts Klick -&amp;gt; Remove file from project&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Es sollte folgende Verzeichnis Struktur überbleiben:&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_6.png|Überbleibende Dateien]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Jetzt müssen die gelöschten Dateien durch die aktuelleren ersetzt werden.&lt;br /&gt;
&lt;br /&gt;
*Dazu kopieren man den gesamten Ordner &#039;&#039;&#039;&#039;&#039;CMSIS&#039;&#039;&#039;&#039;&#039; aus dem CMSIS Download in das Projekt Verzeichnis.&lt;br /&gt;
&lt;br /&gt;
*Aus dem Standard-Peripheral-Library Download kopiert man von &#039;&#039;&#039;&#039;&#039;Libraries\CMSIS\Device\ST\STM32F4xx\Include&#039;&#039;&#039;&#039;&#039; alle Dateien in den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projekt Verzeichnisses&lt;br /&gt;
&lt;br /&gt;
*Aus der Standard-Peripheral-Library kopieren man ebenfalls von &#039;&#039;&#039;&#039;&#039;Libraries\CMSIS\Device\ST\STM32F4xx\Source\Templates&#039;&#039;&#039;&#039;&#039; die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; in den &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner des Projekts&lt;br /&gt;
&lt;br /&gt;
Anschließend müssen die neuen Dateien in der IDE dem Projekt hinzugefügt werden. Dazu benutzt man &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Rechts Klick -&amp;gt; Add files&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
*Aus dem &#039;&#039;&#039;&#039;&#039;CMSIS&#039;&#039;&#039;&#039;&#039; Ordner im Projekt Verzeichnis werden aus den Unterorder &#039;&#039;&#039;&#039;&#039;Include&#039;&#039;&#039;&#039;&#039; folgende Dateien dem Projekt hinzugefügt:&lt;br /&gt;
**arm_common_tables.h&lt;br /&gt;
**arm_const_structs.h&lt;br /&gt;
**arm_math.h&lt;br /&gt;
**core_cm4.h&lt;br /&gt;
**core_cm4_simd.h&lt;br /&gt;
**core_cmFunc.h&lt;br /&gt;
**core_cmInstr.h&lt;br /&gt;
*Alle Dateien aus den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projektes&lt;br /&gt;
*Die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; aus dem &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner&lt;br /&gt;
&lt;br /&gt;
So sollte die Struktur dann aussehen:&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_7.png|Anwenungs-Grundgerüst]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Da einige Dateien der Libraries später bearbeitet werden müssen und Schreibgeschützt sind, weise ich hier schonmal darauf hin, das der Schreibschutz in der IDE über &#039;&#039;&#039;&#039;&#039;Rechts Klick auf die Datei -&amp;gt; Properties -&amp;gt; Häkchen bei &amp;quot;File is read only&amp;quot; entfernen&#039;&#039;&#039;&#039;&#039; entfert werden kann.&lt;br /&gt;
&lt;br /&gt;
Damit die IDE die Header-Dateien der CMSIS Library auch finden kann, weil diese ja nicht im standard Include Ordner &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; liegen, muss unter &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Build Options -&amp;gt; Search Directories&#039;&#039;&#039;&#039;&#039; der Pfad &#039;&#039;&#039;&#039;&#039;CMSIS\Include&#039;&#039;&#039;&#039;&#039; hinzugefügt werden.&lt;br /&gt;
&lt;br /&gt;
Compiliert man jetzt das Projekt mit &#039;&#039;&#039;&#039;&#039;F7&#039;&#039;&#039;&#039;&#039; gibt es ein paar Fehler Meldungen, weil keine Controller-Reihe ausgewählt wurde. Ebenfalls unter &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Build Options -&amp;gt; Compiler Settings -&amp;gt; #defines&#039;&#039;&#039;&#039;&#039; wird der Define &#039;&#039;&#039;&#039;&#039;STM32F40_41xxx&#039;&#039;&#039;&#039;&#039; hinzugefügt.&lt;br /&gt;
&lt;br /&gt;
Beim erneuten Compilieren sollten sich nun keine neuen Fehler ergeben.&lt;br /&gt;
&lt;br /&gt;
===3. Das erste Programm===&lt;br /&gt;
Nachdem ein grundsätzliches &amp;quot;Gerüst&amp;quot; fertig ist, kann man den ersten Code schreiben.&lt;br /&gt;
main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC-&amp;gt;AHB1ENR |= RCC_AHB1ENR_GPIODEN;    //Takt für GPIO aktivieren&lt;br /&gt;
    GPIOD-&amp;gt;MODER |= GPIO_MODER_MODER15_0;   //GPIOD Pin15 als Ausgang&lt;br /&gt;
    GPIOD-&amp;gt;BSRRL |= GPIO_BSRR_BS_15;        //GPIOD Pin15 auf High ziehen&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039; wird dann der Debugger gestartet. Hat der Debugger das Projekt erfolgreich übertragen kann die Ausführung mit &#039;&#039;&#039;&#039;&#039;F5&#039;&#039;&#039;&#039;&#039; begonnen werden.&lt;br /&gt;
&lt;br /&gt;
==Libraries einbinden/verwenden==&lt;br /&gt;
Um Libraries, wie hier im Tutorial, einzubinden, wird ein existierendes Projekt, wie ein im Kapitel [http://www.mikrocontroller.net/articles/STM32_-_Einstieg_mit_Em::Blocks#Das_erste_Projekt_erstellen Das Erste Projekt erstellen] beschrieben wird, vorausgesetzt.&lt;br /&gt;
&lt;br /&gt;
===Einbinden der Standard-Peripheral-Library===&lt;br /&gt;
Um nicht immer die einzelnen Register, wie im ersten &amp;quot;bare-metal&amp;quot; Beispiel, aus dem Reference-Manual zu suchen und zu beschreiben, gibt es von ST die Standard Peripheral Library, die diese Aufgaben übernimmt und mit der sich die &amp;quot;normale/grundlegende&amp;quot; (Alles außer USB und Ethernet) Peripherie recht einfach steuern lässt. Ich kopiere die Standard-Peripheral-Library immer per Hand in das Projekt. Darduch hat man auch gleich die aktuellste Version (in den älteren Version gibt es einige Bugs). &lt;br /&gt;
&lt;br /&gt;
*1. Den Ordner &#039;&#039;&#039;&#039;&#039;Libraries\STM32F4xx_StdPeriph_Driver&#039;&#039;&#039;&#039;&#039; aus dem Standard-Peripheral-Library Download in das Projekt-Verzeichnis kopieren&lt;br /&gt;
*2. Die Datei &#039;&#039;&#039;&#039;&#039;Project\STM32F4xx_StdPeriph_Templates\stm32f4xx_conf.h&#039;&#039;&#039;&#039;&#039; ebenfalls aus dem Standard-Peripheral-Library Download in den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projektes kopieren.&lt;br /&gt;
*3. In der IDE den Include-Path &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\inc&#039;&#039;&#039;&#039;&#039; hinzufügen&lt;br /&gt;
*4. Und das/den Define &#039;&#039;&#039;&#039;&#039;USE_STDPERIPH_DRIVER&#039;&#039;&#039;&#039;&#039; hinzufügen&lt;br /&gt;
*4. Source- und Include-Dateien zum Projekt hinzufügen&lt;br /&gt;
**Achtung: Es dürfen nur die Dateien hinzugefügt werden, für die der Controller auch die entsprechende Peripherie bereit stellt. Diese Dateien dürfen nicht beim STM32F4-Discovery/STM32F407VG hinzugefügt werden.&lt;br /&gt;
***stm32f4xx_dma2d.c/.h&lt;br /&gt;
***stm32f4xx_fmc.c/.h&lt;br /&gt;
***stm32f4xx_ltdc.c/.h&lt;br /&gt;
***stm32f4xx_sai.c/.h&lt;br /&gt;
&lt;br /&gt;
Daraus resultiert folgende Struktur:&lt;br /&gt;
&lt;br /&gt;
[[Datei:stdperiphlib_2.png|Header-Struktur]] [[Datei:stdperiphlib_1.png|Source-Struktur]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Anschließen kann die Standard-Peripheral-Library benutz werden.&lt;br /&gt;
main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);&lt;br /&gt;
&lt;br /&gt;
    GPIO_InitTypeDef GPIOD_InitStructure;&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Mode = GPIO_Mode_OUT;     //Als Ausgang&lt;br /&gt;
    GPIOD_InitStructure.GPIO_OType = GPIO_OType_PP;    //Push-Pull Betrieb&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Pin = GPIO_Pin_15;        //Pin 15 (STM32F4-Discovery: Blaue LED)&lt;br /&gt;
    GPIOD_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;  //Kein Pull-Up oder Pull-Down Widerstand aktiviert&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Speed = GPIO_Speed_25MHz; //25MHz Update-Rate&lt;br /&gt;
    GPIO_Init(GPIOD, &amp;amp;GPIOD_InitStructure);&lt;br /&gt;
&lt;br /&gt;
    GPIO_SetBits(GPIOD, GPIO_Pin_15);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Einbinden der DSP-Library===&lt;br /&gt;
STM32F3 / STM32F4 Microcontroller haben neben der FPU noch einen Digital-Signal-Processor (DSP). Die DSP dient hauptsächlich dazu, viele Daten schnell zu verarbeiten (z.B. Video- oder Audiosignal). Der CMSIS-Download beinhaltet dazu neben der eigentlichen CMSIS-Library auch noch eine DSP-Library. Diese Library stellt sowohl einfache, mathematische Funktionen wie addieren, multiplizieren usw. als auch komplexe Funktionen, wie z.B  einen IIR-Filter, zur Verfügung. Die DSP-Library ist weiter aufgeteilt in kleinere Module, wie z.B. BasicMathFunctions, FilteringFunctions usw. (siehe &#039;&#039;&#039;&#039;&#039;CMSIS\DSP-Library\Source&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
*1. Source-Dateien des benötigten Moduls zum Projekt hinzufügen. (&#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Add files...&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
*2. &#039;&#039;&#039;&#039;&#039;arm_math.h&#039;&#039;&#039;&#039;&#039; in der &#039;&#039;&#039;&#039;&#039;main.c&#039;&#039;&#039;&#039;&#039; einbinden&lt;br /&gt;
*3. Damit die Warnung &amp;quot;Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)&amp;quot; verschwindet, muss der Define &#039;&#039;&#039;&#039;&#039;__FPU_PRESENT&#039;&#039;&#039;&#039;&#039; hinzugefügt werden. (Keine Ahnung, wieso es die Warnung gibt)&lt;br /&gt;
 &lt;br /&gt;
Jetzt kann die DSP-Library verwedet werden. Das Beispiel multipliziert zwei Buffer miteinander. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
#include &amp;quot;arm_math.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    float32_t x[1024];&lt;br /&gt;
    float32_t y[1024];&lt;br /&gt;
    float32_t z[1024];&lt;br /&gt;
&lt;br /&gt;
    for(uint16_t i = 0; i &amp;lt; 1024; i++)&lt;br /&gt;
    {&lt;br /&gt;
        x[i] = i;&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for(uint16_t i = 0; i &amp;lt; 1024; i++)&lt;br /&gt;
    {&lt;br /&gt;
        y[i] = PI;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    arm_mult_f32(x, y, z, 1024);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Startup-Code, Linker-Script, Takt, FPU usw.==&lt;br /&gt;
===Startup-Code===&lt;br /&gt;
Em::Blocks fügt standardmäßig einen Startup-Code mit in das Projekt ein. Die wichtigsten Dinge die darin erledigt werden sind folgende:&lt;br /&gt;
&lt;br /&gt;
*Stack und Heap wird angelgt&lt;br /&gt;
*Die Vector-Table wird angelegt&lt;br /&gt;
*Ein Default Reset-Handler wird implementiert, dieser erledigt folgende aufgaben:&lt;br /&gt;
**Kopieren der definierten Daten aus dem Flash in den SRAM&lt;br /&gt;
**&#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; wird aufgerfen, wenn &#039;&#039;&#039;&#039;&#039;__NO_SYSTEM_INIT&#039;&#039;&#039;&#039;&#039; nicht definiert ist&lt;br /&gt;
**Sprung in die &#039;&#039;&#039;&#039;&#039;main()&#039;&#039;&#039;&#039;&#039; Funktion&lt;br /&gt;
*Allen anderen Interrupt-Handler wird eine Default-Funktion &#039;&#039;&#039;&#039;&#039;def_irq_handler&#039;&#039;&#039;&#039;&#039; mit einer &#039;&#039;&#039;&#039;&#039;while(1)&#039;&#039;&#039;&#039;&#039;-Schleife zugewiesen, falls kein anderer Interrupt-Handler existiert.&lt;br /&gt;
&lt;br /&gt;
Normalerweise muss am Startup-Code nichts verändert werden.&lt;br /&gt;
&lt;br /&gt;
===Linker-Script===&lt;br /&gt;
Em::Blocks stellt zwei fertige Linker-Scripts bereit, eins für die Ausführung des Programmes aus dem Flash (&#039;&#039;&#039;&#039;&#039;*_flash.ld&#039;&#039;&#039;&#039;&#039;), das andere für die Ausführung aus dem SRAM (&#039;&#039;&#039;&#039;&#039;*_sram.ld&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Normalerweise muss auch hier nichts geändert werden, es sei den Daten sollen in bestimmten Adressbereichen abgelegt werden (z.B. im Core-Coupled RAM), was ich später noch zum Tutorial hinzufüge.&lt;br /&gt;
&lt;br /&gt;
===Der Takt===&lt;br /&gt;
Jeder Controller oder Prozessor braucht einen Takt, indem er die einzelnen Maschinen-Befehle abarbeiten kann.&lt;br /&gt;
Bei den STM32 Mikrocontrollern kann dieser Takt aus verschiedenen Quellen kommen:&lt;br /&gt;
&lt;br /&gt;
1. High Speed Internal Oszillator (HSI)&lt;br /&gt;
&lt;br /&gt;
2. High Speed External Oszillator (HSE)&lt;br /&gt;
&lt;br /&gt;
3. Low Speed Internal Oszillator (LSI)&lt;br /&gt;
&lt;br /&gt;
4. Low Speed External Oszillator (LSE)&lt;br /&gt;
&lt;br /&gt;
5. Phase-Locked Loop (PLL) (generiert den Takt aus den ersten vier Taktquellen durch Teiler und Faktoren)&lt;br /&gt;
&lt;br /&gt;
Nach einem Reset wird der Controller aus der HSI Taktquelle versorgt (16MHz beim STM32F407VG). Um die voll Performance des Controllers zu erreichen muss die PLL verwendet werden, welche den Takt durch geschickte Teiler und Faktoren vervielfältigt, sodass am Ende der Controller mit der maximalen Taktfrequenz läuft. Die notwendige Initialisierung der PLL findet in der Funktion &#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; statt. Die PLL erzeugt zunächst einen Basistakt:&lt;br /&gt;
&lt;br /&gt;
PLL_VCO = (F_HSE / PLL_M) * PLL_N&lt;br /&gt;
&lt;br /&gt;
Aus diesem Takt wird dann der Takt für den Controller-Kern abgeleitet:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = PLL_VCO / PLL_P&lt;br /&gt;
&lt;br /&gt;
Und der Takt für SDIO / USB / RNG (48MHz):&lt;br /&gt;
&lt;br /&gt;
48MHz = PLL_VCO / PLL_Q&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Durch weiter Teiler werden, die Takte für die einzelnen Busse erzeugt, da diese nicht alle beliebig schnell betrieben werden dürfen.&lt;br /&gt;
&lt;br /&gt;
Genaue Angaben findet man zu dem jeweiligen Clock-System des Controllers im Reference Manual.&lt;br /&gt;
&lt;br /&gt;
Ein Blick in den &amp;quot;Kommentar-Header&amp;quot; verrät, dass von einem externen (HSE) Oszillator von 25MHz ausgegangen wird, der die PLL versorgen soll.&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((25MHz / PLL_M(25)) * PLL_N(336)) / PLL_P(2) = 168MHz&lt;br /&gt;
&lt;br /&gt;
Allerdings stimmt diese Rechnung natürlich nur, wenn wirklich ein 25MHz Quarz am Controller angeschlossen ist. Auf dem STM32F4-Discovery Board befindet sich aber nur ein 8MHz Quarz. Demnach gilt:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((8MHz / PLL_M(25)) * PLL_N(336)) / PLL_P(2) = 53.76MHz&lt;br /&gt;
&lt;br /&gt;
Der Controller läuft also nur mit 53.76MHz, wenn wie ober beschrieben ein Projekt erstellt wird. Allerdings kann dieses Problem durch ändern von den betroffen Defines behoben werden:&lt;br /&gt;
 &lt;br /&gt;
*Dazu geht man in die &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; Datei und passt zur Vollständigkeit erstmal die zum Controller passende Tabelle im &amp;quot;Kommentar-Header&amp;quot; an (Z.57f):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      HSE Frequency(Hz)                      | 8000000&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      PLL_M                                  | 8&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Danach passt man den PPL_M Define (Z.254) an:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/************************* PLL Parameters *************************************/&lt;br /&gt;
/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */&lt;br /&gt;
#define PLL_M      8&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Außerdem muss man den HSE_VALUE Define in der &#039;&#039;&#039;&#039;&#039;inc/stm32f4xx.h&#039;&#039;&#039;&#039;&#039; angepasst werden (Z.122):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#if !defined  (HSE_VALUE)&lt;br /&gt;
  #define HSE_VALUE    ((uint32_t)8000000) /*!&amp;lt; Value of the External oscillator in Hz */&lt;br /&gt;
&lt;br /&gt;
#endif /* HSE_VALUE */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine neue Berechnung zeigt:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((8MHz / PLL_M(8)) * PLL_N(336)) / PLL_P(2) = 168MHz&lt;br /&gt;
&lt;br /&gt;
Jetzt läuft der Controller mit maximaler Geschwindigkeit.&lt;br /&gt;
&lt;br /&gt;
Die Theorie wird durch folgendes Programm verifiziert. Der geviertelte System-Takt SYSCLK wir am Pin PC9 ausgegeben. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);&lt;br /&gt;
&lt;br /&gt;
    GPIO_InitTypeDef GPIOC_InitStructure;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Mode = GPIO_Mode_AF;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_OType = GPIO_OType_PP;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Pin = GPIO_Pin_9;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;&lt;br /&gt;
    GPIO_Init(GPIOC, &amp;amp;GPIOC_InitStructure);&lt;br /&gt;
&lt;br /&gt;
    RCC_MCO2Config(RCC_MCO2Source_SYSCLK, RCC_MCO2Div_4);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Die FPU===&lt;br /&gt;
====Allgemeines====&lt;br /&gt;
STM32F3 und STM32F4 Controller haben eine FPU.&lt;br /&gt;
Damit die FPU richtig verwendet wird, müssen normalerweise zwei Bedingungen erfüllt sein:&lt;br /&gt;
&lt;br /&gt;
1. Der Controller muss die FPU Hardware-seitig aktivieren&lt;br /&gt;
&lt;br /&gt;
2. Damit die FPU auch was zu tuen bekommt, müssen vom Compiler FPU-Instructions erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
Die Em::Blocks IDE verwendet standardmäßig die FPU, wenn eine Vorhanden ist. Hier wird die FPU Hardware-seitig aktiviert (&#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; Z.341):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* FPU settings ------------------------------------------------------------*/&lt;br /&gt;
  #if (__FPU_PRESENT == 1) &amp;amp;&amp;amp; (__FPU_USED == 1)&lt;br /&gt;
    SCB-&amp;gt;CPACR |= ((3UL &amp;lt;&amp;lt; 10*2)|(3UL &amp;lt;&amp;lt; 11*2));  /* set CP10 and CP11 Full Access */&lt;br /&gt;
  #endif&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
__FPU_PRESENT wird in der &#039;&#039;&#039;&#039;&#039;stm32f4xx.h&#039;&#039;&#039;&#039;&#039; definiert.&lt;br /&gt;
__FPU_USED wird von der IDE übernommen (siehe Build-Log): &#039;&#039;&#039;&#039;&#039;-D__FPU_USED&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Außerdem wird der Compiler von der IDE standardmäßig mit dem Argument &#039;&#039;&#039;&#039;&#039;-mfloat-abi=hard&#039;&#039;&#039;&#039;&#039; aufgerufen, wodurch FPU-Instructions erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
====FPU abschalten====&lt;br /&gt;
Um die FPU ab zu schalten (Mir würde jetzt nur Strom sparen als Grund einfallen) geht man wie folgt vor:&lt;br /&gt;
&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; Device -&amp;gt; Policy&#039;&#039;&#039;&#039;&#039; wählt man &#039;&#039;&#039;&#039;&#039;Use target settings&#039;&#039;&#039;&#039;&#039; und über nimmt die Einstellungen, die vorher dort eingetragen waren, allerdings lässt man das Feld &#039;&#039;&#039;&#039;&#039;FP-hardware&#039;&#039;&#039;&#039;&#039; frei.&lt;br /&gt;
&lt;br /&gt;
[[Datei:fpu_1.png|FPU Abschalten Schritt 1]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;Compiler Settings -&amp;gt; Policy&#039;&#039;&#039;&#039;&#039; wählt man dann &#039;&#039;&#039;&#039;&#039;Use target options only&#039;&#039;&#039;&#039;&#039;. Dann kann man unter &#039;&#039;&#039;&#039;&#039;Categories&#039;&#039;&#039;&#039;&#039; die Option &#039;&#039;&#039;&#039;&#039;ARM FPU architecture&#039;&#039;&#039;&#039;&#039; auswählen. Dort stehen dann drei Möglichkeiten für die FPU zur Verfügung:&lt;br /&gt;
&lt;br /&gt;
1. Software-FPU-Library für Gleitkomma-Berechnung verwenden - Keine FPU-Instructions werden generiert (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=soft&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
2. Eine Mischung aus Software- und Hardware-FPU wird verwendet (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=softfp&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
3. Hardware-FPU wird für Gleitkomma-Berechnungen verwendet (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=hard&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
[[Datei:fpu_2.png|FPU Abschalten Schritt 2]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Um die FPU ab zu schalten wählt man natürlich die erste Möglichkeit.&lt;br /&gt;
Bei der 2. und 3. Möglichkeit fügt die IDE auch den Define &#039;&#039;&#039;&#039;&#039;__FPU_USED&#039;&#039;&#039;&#039;&#039; hinzu. Bei Der ersten Möglichkeit nicht. Der Code muss also nicht verändert / auskommentiert werden.&lt;br /&gt;
&lt;br /&gt;
Um die FPU wieder zu aktivieren müssen alle Schritte wieder rückgängig gemacht werden.&lt;br /&gt;
&lt;br /&gt;
Am besten ist es einfach mal alle Möglichkeiten im Einzelschritt durch zu probieren. Dann stellt man schnell fest, ob die FPU aktiviert wir oder nicht. Ein Blick in den erweiterten &#039;&#039;&#039;&#039;&#039;Build-Log&#039;&#039;&#039;&#039;&#039; gibt auch schnell Aufschluss darüber, wie der Compiler aufgerufen wird (siehe Kapitel [http://www.mikrocontroller.net/articles/STM32_-_Einstieg_mit_Em::Blocks#Compilieren Compilieren]).&lt;br /&gt;
&lt;br /&gt;
====Test Programm für die FPU====&lt;br /&gt;
Hier ein kleines Testprogramm, dass misst wie viele Taktzyklen für eine Gleitkomma-Multiplikation gebraucht werden. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define CORE_SysTickEn()    (*((u32*)0xE0001000)) = 0x40000001&lt;br /&gt;
#define CORE_SysTickDis()   (*((u32*)0xE0001000)) = 0x40000000&lt;br /&gt;
#define CORE_GetSysTick()   (*((u32*)0xE0001004))&lt;br /&gt;
&lt;br /&gt;
uint32_t t1, t2, dt;&lt;br /&gt;
float x, y, z;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    x = 53.64f;&lt;br /&gt;
    y = 0.27f;&lt;br /&gt;
&lt;br /&gt;
    CORE_SysTickEn();&lt;br /&gt;
    t1 = CORE_GetSysTick();&lt;br /&gt;
&lt;br /&gt;
    z = x * y;&lt;br /&gt;
&lt;br /&gt;
    t2 = CORE_GetSysTick();&lt;br /&gt;
    CORE_SysTickDis();&lt;br /&gt;
&lt;br /&gt;
    dt = (t2 - t1) - 9; //9 Takt-Zyklen werden für die Messung gebraucht &lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Booten aus dem SRAM==&lt;br /&gt;
STM32 Controller haben die Möglichkeit Code aus dem Flash als auch aus dem SRAM auszuführen. Um eine Anwenung per Debugger in des SRAM zu laden sind nur wenige Schritte erforderlich:&lt;br /&gt;
&lt;br /&gt;
*Um das Linkerscript für den SRAM zu verwenden geht man zu: &#039;&#039;&#039;&#039;&#039;Build options... -&amp;gt; Device&#039;&#039;&#039;&#039;&#039; dort wählt man unter &#039;&#039;&#039;&#039;&#039;Policy&#039;&#039;&#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;Use target settings&#039;&#039;&#039;&#039;&#039; aus und übernimmt die vorherigen Einstellungen, nur unter &#039;&#039;&#039;&#039;&#039;Linker script*&#039;&#039;&#039;&#039;&#039; gibt man &#039;&#039;&#039;&#039;&#039;.\stm32f407vg_sram.ld&#039;&#039;&#039;&#039;&#039; an&lt;br /&gt;
&lt;br /&gt;
*Dann muss man noch unter &#039;&#039;&#039;&#039;&#039;Debug -&amp;gt; Interfaces -&amp;gt; Settings&#039;&#039;&#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;Vector table start&#039;&#039;&#039;&#039;&#039; auf 0x20000000 ändern und &#039;&#039;&#039;&#039;&#039;Execute from RAM&#039;&#039;&#039;&#039;&#039; auswählen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:bootsram_1.png Booten aus dem SRAM]] [[Datei:bootsram_2.png Booten aus dem SRAM]]&lt;br /&gt;
&lt;br /&gt;
Anschließend kann man die Anwendung ganz normal debuggen. Nach einem Reset muss die Anwenung erneut mit dem Debugger gestartet werden.&lt;br /&gt;
&lt;br /&gt;
=Fortsetzung folgt..=&lt;br /&gt;
Kritik, Wünsche usw. sind gerne erwünscht, am besten hier in den Thread posten: [http://www.mikrocontroller.net/topic/323750 Neues STM32 Tutorial]&lt;br /&gt;
&lt;br /&gt;
[[Category:ARM]]&lt;br /&gt;
[[Category:STM32]]&lt;/div&gt;</summary>
		<author><name>Avrprogger</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=STM32_-_Einstieg_mit_Em::Blocks&amp;diff=81569</id>
		<title>STM32 - Einstieg mit Em::Blocks</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=STM32_-_Einstieg_mit_Em::Blocks&amp;diff=81569"/>
		<updated>2014-02-13T14:18:19Z</updated>

		<summary type="html">&lt;p&gt;Avrprogger: gj&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In diesem Tutorial werde ich versuchen, möglichst einfach, die ersten Schritte zur Entwicklung von STM32 Anwenungen mit der Em::Blocks IDE zu erklären. Hier soll nicht so stark auf die einzelnen Peripherie-Module der Controller eingegangen werden, sondern mehr auf die IDE und die verschieden Libraries, wie die CMSIS Library, die DSP-Library, die Standard-Peripheral-Library, die USB-Library und vllt. über Ethernet. Ich denke ein Kapitel zu FreeRTOS wird es auch geben. Auserdem steht im Vordergrund Sachen wie z.B. booten aus dem SRAM, In-Application-Programming, FPU, Core-Coupled-RAM usw. Mal sehn wie weit ich komme ;)&lt;br /&gt;
&lt;br /&gt;
==Die Entwicklungsumgebung==&lt;br /&gt;
===Hardware===&lt;br /&gt;
Zum testen der Anwendungen, benutze ich das STM32F4-Discovery Board, welches einen Debugger, Peripherie und natürlich einen STM32 Controller (STM32F407VGT6) enthält. Deshalb sind alle Beispiele hier für den STM32F407VG Controller ausgelegt, können aber meisten 1:1 auf andere Controller portiert werden. Ich werde auch möglichsts keine STM32F4-Discovery Board spezifischen Libraries verwenden, damit der Portierungs-Vorgang möglichsts einfach bleibt.&lt;br /&gt;
&lt;br /&gt;
===Software===&lt;br /&gt;
In diesem Tutorial verwende ich [http://www.emblocks.org/ Em::Blocks] als IDE. Em::Blocks ist eine kostenlose, uneingeschränkte IDE, die alle STM32 Mikrcontroller unterstützt und sehr einfach zu bedienen ist.&lt;br /&gt;
nach dem Download kann die IDE per Dialog, sehr einfach, installiert werden. Als Compiler beinhaltet Em::Blocks den &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
Die IDE unterstützt zurzeit den ST-Link, den J-Link und es gibt eine Generic-Vorlage, durch welche andere Debugger konfiguriert werden können.&lt;br /&gt;
&lt;br /&gt;
Außerdem muss noch der passende Treiber für den Debugger installiert werden. Verwendet man ein Discovery-Board muss der [http://www.st.com/web/catalog/tools/FM146/CL1984/SC724/SS1677/PF251168 ST-Link/V2]-Treiber heruntergeladen und installiert werden. (Die Installation muss evtl. als Administrator ausgeführt werden, da sonst die Installation unvollständig wird.) Nach der Installation des Treibers kann man den Debugger über die entsprechende USB Schnittstelle an den PC anschließen und es sollte die Meldung von Windows kommen, dass der richtige Treiber gefunden wurde.&lt;br /&gt;
&lt;br /&gt;
===Libraries===&lt;br /&gt;
Zum programmieren benötigt man noch die [http://www.arm.com/products/processors/cortex-m/cortex-microcontroller-software-interface-standard.php CMSIS] und die Standard-Peripheral-Library (z.B. für die F4 Controller [http://www.st.com/stonline/stappl/productcatalog/app?page=partNumberSearchPage&amp;amp;levelid=SS1577&amp;amp;parentid=1743&amp;amp;resourcetype=SW Standard-Peripheral-Library-F4]), die man am besten in einen Ordner (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\STM32&#039;&#039;&#039;&#039;&#039;) entpackt&lt;br /&gt;
&lt;br /&gt;
==Basis-Wissen zur IDE==&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von Dateien zum Projekt===&lt;br /&gt;
Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf &amp;lt;ProjektName&amp;gt; -&amp;gt; Add files...&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Enfernen von Dateien aus dem Projekt===&lt;br /&gt;
Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf die Datei / mehrere Dateien auswählen -&amp;gt; Remove file from project&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
Die Dateien werden lediglich aus dem Projekt entfernt und nicht von der Festplatte gelöscht.&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von Include-Pfaden===&lt;br /&gt;
Sofern die Include-Datei(en) nicht im standard Include-Ordner &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; des Projektes liegen, muss man den Pfad zum Projekt hinzufügen, damit der Compiler die Include-Dateien später auch finden kann. Man geht wie folgt vor: Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; Search Directories -&amp;gt; Add&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von globalen Defines zum Build===&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; #defines&#039;&#039;&#039;&#039;&#039; können globale Defines hinzugefügt werden.&lt;br /&gt;
&lt;br /&gt;
===Compilieren===&lt;br /&gt;
Entweder über das &#039;&#039;&#039;&#039;&#039;Build&#039;&#039;&#039;&#039;&#039; Menü oder über &#039;&#039;&#039;&#039;&#039;F7&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Um eine genau Ausgabe des Compiler-Aufrufes mit allen Argumenten zu bekommen, geht man im &#039;&#039;&#039;&#039;&#039;Settings&#039;&#039;&#039;&#039;&#039; Menü auf &#039;&#039;&#039;&#039;&#039;Tools...&#039;&#039;&#039;&#039;&#039; und dann auf &#039;&#039;&#039;&#039;&#039;Toolchain executables&#039;&#039;&#039;&#039;&#039;. Ganz unten, unter &#039;&#039;&#039;&#039;&#039;Logging&#039;&#039;&#039;&#039;&#039; kann man dann &#039;&#039;&#039;&#039;&#039;Full command line&#039;&#039;&#039;&#039;&#039; auswählen.&lt;br /&gt;
&lt;br /&gt;
====Compiler Optionen====&lt;br /&gt;
=====Optimierung=====&lt;br /&gt;
Standardmäßig verwendet Em::Blocks keine Optimierung. Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; Categories: Optimization&#039;&#039;&#039;&#039;&#039; kann zwischen verschieden Optimierungen ausgewählt werden.&lt;br /&gt;
&lt;br /&gt;
=====Verschiedene C-Standards=====&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; Categories: Language standard&#039;&#039;&#039;&#039;&#039; kann man zwischen verschieden C-Standard auswählen, wie z.B, C99.&lt;br /&gt;
(Mit C99 können auch die Lauf-Variable in der for-Schleife deklariert werden: for(int i;..))&lt;br /&gt;
&lt;br /&gt;
===Debuggen===&lt;br /&gt;
*Als erstes den Debugger starten über das &#039;&#039;&#039;&#039;&#039;Debug&#039;&#039;&#039;&#039;&#039; Menü und &#039;&#039;&#039;&#039;&#039;Start/stop Debug Session&#039;&#039;&#039;&#039;&#039; oder über &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
*Danach läuft die Anwendung auf dem Controller und warten im &#039;&#039;&#039;&#039;&#039;Reset_Handler&#039;&#039;&#039;&#039;&#039; auf Einzelschritt- bzw. Run- Befehle (&#039;&#039;&#039;&#039;&#039;F5, F10, F11&#039;&#039;&#039;&#039;&#039; usw..(siehe &#039;&#039;&#039;&#039;&#039;Debug-Menü&#039;&#039;&#039;&#039;&#039; für alle Möglichkeiten))&lt;br /&gt;
&lt;br /&gt;
*Mit &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039; wird die Debug-Session auch wieder beendet&lt;br /&gt;
&lt;br /&gt;
*Unter &#039;&#039;&#039;&#039;&#039;Debug -&amp;gt; Interfaces -&amp;gt; Target settings&#039;&#039;&#039;&#039;&#039; können Eigenschaften, wie z.B &#039;&#039;&#039;&#039;&#039;Run to main()&#039;&#039;&#039;&#039;&#039; aktiviert werden.&lt;br /&gt;
&lt;br /&gt;
===Projekt als Template abspeichern===&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;File -&amp;gt; Save project as template...&#039;&#039;&#039;&#039;&#039;. Das Template erscheint dann im Projekt-Dialog unter &#039;&#039;&#039;&#039;&#039;User templates&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Das erste Projekt erstellen==&lt;br /&gt;
Hier erkläre ich, wie man am Besten (aus meiner Sicht), ein neues Projekt von Grund auf erstellt, sodass man hinterher, den Controller-Kern über die CMSIS-Library und die Peripherie über die Register steuern kann.&lt;br /&gt;
&lt;br /&gt;
===1. Projekt mit der IDE erstellen===&lt;br /&gt;
Nach der Installation der oben beschriebenen Komponenten erstellt man am besten ein Verzeichnis (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\EmBlocks&#039;&#039;&#039;&#039;&#039;), indem später alle Projekte gespeichert werden. Für Libraries kann man auch noch ein Verzeichnis (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\STM32&#039;&#039;&#039;&#039;&#039;) erstellen, wo alle Libraries gespeichert werden, die man für die Projekt brauchen.&lt;br /&gt;
&lt;br /&gt;
Als nächstes starten man EmBlocks. Bei dem ersten Start öffnet sich ein Fenster, wo verschiedene Compiler angezeigt werden, die Em::Blocks findet. Dort wählt man den &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039; aus und klickt &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039;. Nun sollte sich das Hauptfenster von Em::Blocks öffnen. Über &#039;&#039;&#039;&#039;&#039;Create a new Project&#039;&#039;&#039;&#039;&#039; oder &#039;&#039;&#039;&#039;&#039;File -&amp;gt; New -&amp;gt; Project&#039;&#039;&#039;&#039;&#039; ruft man den Projekt-Dialog auf und kann ein neues Projekt erzeugen.&lt;br /&gt;
&lt;br /&gt;
Auf der Ersten Seite wählen man den &#039;&#039;&#039;&#039;&#039;STmicro-ARM&#039;&#039;&#039;&#039;&#039; Projekt-Typ aus.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_1.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auf der nächsten Seite wird man darauf hingewiesen, dass das der entsprechende Projekt-Typ-Dialog ausgeführt wird. Hier kann man ein Häkchen bei &#039;&#039;&#039;&#039;&#039;Skip this page next time&#039;&#039;&#039;&#039;&#039; setzen und auf &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; klicken.&lt;br /&gt;
&lt;br /&gt;
Im nächsten Schritt wählen man das zuvor erstellt Verzeichnis unter &#039;&#039;&#039;&#039;&#039;Folder to create Project in&#039;&#039;&#039;&#039;&#039; aus, indem später alle Projekt gespeichert werden. Außerdem geben wir dem Projekt einen Namen (z.B. &#039;&#039;&#039;&#039;&#039;FirstProject&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_2.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danach muss man einen Compiler auswählen und bestimmen, welche Projekt-Konfigurationen erszeugt werden sollen. Unter &#039;&#039;&#039;&#039;&#039;Compiler&#039;&#039;&#039;&#039;&#039; wählt man &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039; und man kann das Häkchen bei &#039;&#039;&#039;&#039;&#039;Create &amp;quot;Release&amp;quot; configuration&#039;&#039;&#039;&#039;&#039; entfernen, da diese unnötig ist, die Debug-Konfiguration sollte eig. immer ausreichen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_3.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auf den folgenden Seite wird der Controller ausgewählt. Verwendet man ein STM32F4-Discovery Board müssen folgende Dinge gewählt werden: &#039;&#039;&#039;&#039;&#039;Cortex_M4 (F3xx - F4xx) -&amp;gt; STM32F4xx (Cortex M4 with FPU) -&amp;gt; STM32F407VG&#039;&#039;&#039;&#039;&#039;. Leider sind die Auswahl Möglichkeiten nicht ganz richtig, da auch die F3 Controller einen Cortex M4 Kern und eine FPU haben (Ist aber nicht so wichtig, ist nur eine formale Sache). Außerdem entfernt man das Häkchen bei &#039;&#039;&#039;&#039;&#039;Standard Peripherals Library&#039;&#039;&#039;&#039;&#039; (Wie man die Standard-Peripheral-Library einbindet und verwendet erkläre ich später). Man kann auch das Häkchen bei &#039;&#039;&#039;&#039;&#039;Create hex file for Realease target&#039;&#039;&#039;&#039;&#039; entfernen.&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;Stack Size&#039;&#039;&#039;&#039;&#039; und &#039;&#039;&#039;&#039;&#039;Heap Size&#039;&#039;&#039;&#039;&#039; wird die Größe von Stack und Heap festgelegt. Für eine erste Anwendung kann man die Einstellungen so lassen (Stack-Size: 0x0100 =&amp;gt; 256 Byte Stack und Heap-Size: 0x0000 =&amp;gt; kein Heap). Mit &#039;&#039;&#039;&#039;&#039;Finish&#039;&#039;&#039;&#039;&#039; ist der Projekt Dialog abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_4.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danach sollten sich zwei neue Fenster öffnen, um die Debug-Eigenschaften fest zu legen.&lt;br /&gt;
Verwendet man ein Discovery Board/ST-Link müssen die Einstellungen wie auf dem Bild gewählt werden. Über den Button &#039;&#039;&#039;&#039;&#039;Settings&#039;&#039;&#039;&#039;&#039; öffnet sich das zweite Fenster, falls sich dieses nicht schon von alleine öffnen sollte. Nach den Schließen der Fenster über &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; ist der Projekt Dialog beendet und ein neues Projekt steht zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_5_1.png|Debug Eigenschaften 1. Fenster]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_5_2.png|Debug Eigenschaften 2. Fenster]]&lt;br /&gt;
&lt;br /&gt;
===2. CMSIS-Library und Startup-Code hinzufügen===&lt;br /&gt;
Wenn man sich, nachdem man ein neues Projekt in der IDE erstellt hat, die bereits vorhandenen Dateien im Projekt ansieht, stellt man fest, das bereits ein Ordner &#039;&#039;&#039;&#039;&#039;cmsis&#039;&#039;&#039;&#039;&#039; existiert, der einige wichtige Include-Dateien der CMSIS-Library enthält. Allerdings sind das wirklich nur die wichtigsten Include-Dateien der CMSIS-Library und dazu noch, die aus einer älternen Version. Ich ziehe es deshalb vor die &amp;quot;Mini-CMSIS-Libraray&amp;quot; und die &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c/.h&#039;&#039;&#039;&#039;&#039; Dateien des Projektes durch aktuellere Versionen zu ersetzen. So ist später auch die Integration  von anderen Libraries, wie z.B. der CMSIS-DSP-Libarary einfacher.  &lt;br /&gt;
&lt;br /&gt;
Zunächst gehen man in das Projekt-Verzeichnis und löscht:&lt;br /&gt;
*Den Ordner &#039;&#039;&#039;&#039;&#039;cmsis&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Alle Dateien im Include Verzeichnis &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; im &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner&lt;br /&gt;
&lt;br /&gt;
Außerdem entfernt man auch alle gelöschten Dateien in der IDE aus dem Projekt mit &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Rechts Klick -&amp;gt; Remove file from project&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Es sollte folgende Verzeichnis Struktur überbleiben:&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_6.png|Überbleibende Dateien]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Jetzt müssen die gelöschten Dateien durch die aktuelleren ersetzt werden.&lt;br /&gt;
&lt;br /&gt;
*Dazu kopieren man den gesamten Ordner &#039;&#039;&#039;&#039;&#039;CMSIS&#039;&#039;&#039;&#039;&#039; aus dem CMSIS Download in das Projekt Verzeichnis.&lt;br /&gt;
&lt;br /&gt;
*Aus dem Standard-Peripheral-Library Download kopiert man von &#039;&#039;&#039;&#039;&#039;Libraries\CMSIS\Device\ST\STM32F4xx\Include&#039;&#039;&#039;&#039;&#039; alle Dateien in den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projekt Verzeichnisses&lt;br /&gt;
&lt;br /&gt;
*Aus der Standard-Peripheral-Library kopieren man ebenfalls von &#039;&#039;&#039;&#039;&#039;Libraries\CMSIS\Device\ST\STM32F4xx\Source\Templates&#039;&#039;&#039;&#039;&#039; die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; in den &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner des Projekts&lt;br /&gt;
&lt;br /&gt;
Anschließend müssen die neuen Dateien in der IDE dem Projekt hinzugefügt werden. Dazu benutzt man &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Rechts Klick -&amp;gt; Add files&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
*Aus dem &#039;&#039;&#039;&#039;&#039;CMSIS&#039;&#039;&#039;&#039;&#039; Ordner im Projekt Verzeichnis werden aus den Unterorder &#039;&#039;&#039;&#039;&#039;Include&#039;&#039;&#039;&#039;&#039; folgende Dateien dem Projekt hinzugefügt:&lt;br /&gt;
**arm_common_tables.h&lt;br /&gt;
**arm_const_structs.h&lt;br /&gt;
**arm_math.h&lt;br /&gt;
**core_cm4.h&lt;br /&gt;
**core_cm4_simd.h&lt;br /&gt;
**core_cmFunc.h&lt;br /&gt;
**core_cmInstr.h&lt;br /&gt;
*Alle Dateien aus den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projektes&lt;br /&gt;
*Die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; aus dem &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner&lt;br /&gt;
&lt;br /&gt;
So sollte die Struktur dann aussehen:&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_7.png|Anwenungs-Grundgerüst]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Da einige Dateien der Libraries später bearbeitet werden müssen und Schreibgeschützt sind, weise ich hier schonmal darauf hin, das der Schreibschutz in der IDE über &#039;&#039;&#039;&#039;&#039;Rechts Klick auf die Datei -&amp;gt; Properties -&amp;gt; Häkchen bei &amp;quot;File is read only&amp;quot; entfernen&#039;&#039;&#039;&#039;&#039; entfert werden kann.&lt;br /&gt;
&lt;br /&gt;
Damit die IDE die Header-Dateien der CMSIS Library auch finden kann, weil diese ja nicht im standard Include Ordner &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; liegen, muss unter &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Build Options -&amp;gt; Search Directories&#039;&#039;&#039;&#039;&#039; der Pfad &#039;&#039;&#039;&#039;&#039;CMSIS\Include&#039;&#039;&#039;&#039;&#039; hinzugefügt werden.&lt;br /&gt;
&lt;br /&gt;
Compiliert man jetzt das Projekt mit &#039;&#039;&#039;&#039;&#039;F7&#039;&#039;&#039;&#039;&#039; gibt es ein paar Fehler Meldungen, weil keine Controller-Reihe ausgewählt wurde. Ebenfalls unter &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Build Options -&amp;gt; Compiler Settings -&amp;gt; #defines&#039;&#039;&#039;&#039;&#039; wird der Define &#039;&#039;&#039;&#039;&#039;STM32F40_41xxx&#039;&#039;&#039;&#039;&#039; hinzugefügt.&lt;br /&gt;
&lt;br /&gt;
Beim erneuten Compilieren sollten sich nun keine neuen Fehler ergeben.&lt;br /&gt;
&lt;br /&gt;
===3. Das erste Programm===&lt;br /&gt;
Nachdem ein grundsätzliches &amp;quot;Gerüst&amp;quot; fertig ist, kann man den ersten Code schreiben.&lt;br /&gt;
main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC-&amp;gt;AHB1ENR |= RCC_AHB1ENR_GPIODEN;    //Takt für GPIO aktivieren&lt;br /&gt;
    GPIOD-&amp;gt;MODER |= GPIO_MODER_MODER15_0;   //GPIOD Pin15 als Ausgang&lt;br /&gt;
    GPIOD-&amp;gt;BSRRL |= GPIO_BSRR_BS_15;        //GPIOD Pin15 auf High ziehen&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039; wird dann der Debugger gestartet. Hat der Debugger das Projekt erfolgreich übertragen kann die Ausführung mit &#039;&#039;&#039;&#039;&#039;F5&#039;&#039;&#039;&#039;&#039; begonnen werden.&lt;br /&gt;
&lt;br /&gt;
==Libraries einbinden/verwenden==&lt;br /&gt;
Um Libraries, wie hier im Tutorial, einzubinden, wird ein existierendes Projekt, wie ein im Kapitel [http://www.mikrocontroller.net/articles/STM32_-_Einstieg_mit_Em::Blocks#Das_erste_Projekt_erstellen Das Erste Projekt erstellen] beschrieben wird, vorausgesetzt.&lt;br /&gt;
&lt;br /&gt;
===Einbinden der Standard-Peripheral-Library===&lt;br /&gt;
Um nicht immer die einzelnen Register, wie im ersten &amp;quot;bare-metal&amp;quot; Beispiel, aus dem Reference-Manual zu suchen und zu beschreiben, gibt es von ST die Standard Peripheral Library, die diese Aufgaben übernimmt und mit der sich die &amp;quot;normale/grundlegende&amp;quot; (Alles außer USB und Ethernet) Peripherie recht einfach steuern lässt. Ich kopiere die Standard-Peripheral-Library immer per Hand in das Projekt. Darduch hat man auch gleich die aktuellste Version (in den älteren Version gibt es einige Bugs). &lt;br /&gt;
&lt;br /&gt;
*1. Den Ordner &#039;&#039;&#039;&#039;&#039;Libraries\STM32F4xx_StdPeriph_Driver&#039;&#039;&#039;&#039;&#039; aus dem Standard-Peripheral-Library Download in das Projekt-Verzeichnis kopieren&lt;br /&gt;
*2. Die Datei &#039;&#039;&#039;&#039;&#039;Project\STM32F4xx_StdPeriph_Templates\stm32f4xx_conf.h&#039;&#039;&#039;&#039;&#039; ebenfalls aus dem Standard-Peripheral-Library Download in den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projektes kopieren.&lt;br /&gt;
*3. In der IDE den Include-Path &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\inc&#039;&#039;&#039;&#039;&#039; hinzufügen&lt;br /&gt;
*4. Und das/den Define &#039;&#039;&#039;&#039;&#039;USE_STDPERIPH_DRIVER&#039;&#039;&#039;&#039;&#039; hinzufügen&lt;br /&gt;
*4. Source- und Include-Dateien zum Projekt hinzufügen&lt;br /&gt;
**Achtung: Es dürfen nur die Dateien hinzugefügt werden, für die der Controller auch die entsprechende Peripherie bereit stellt. Diese Dateien dürfen nicht beim STM32F4-Discovery/STM32F407VG hinzugefügt werden.&lt;br /&gt;
***stm32f4xx_dma2d.c/.h&lt;br /&gt;
***stm32f4xx_fmc.c/.h&lt;br /&gt;
***stm32f4xx_ltdc.c/.h&lt;br /&gt;
***stm32f4xx_sai.c/.h&lt;br /&gt;
&lt;br /&gt;
Daraus resultiert folgende Struktur:&lt;br /&gt;
&lt;br /&gt;
[[Datei:stdperiphlib_2.png|Header-Struktur]] [[Datei:stdperiphlib_1.png|Source-Struktur]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Anschließen kann die Standard-Peripheral-Library benutz werden.&lt;br /&gt;
main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);&lt;br /&gt;
&lt;br /&gt;
    GPIO_InitTypeDef GPIOD_InitStructure;&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Mode = GPIO_Mode_OUT;     //Als Ausgang&lt;br /&gt;
    GPIOD_InitStructure.GPIO_OType = GPIO_OType_PP;    //Push-Pull Betrieb&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Pin = GPIO_Pin_15;        //Pin 15 (STM32F4-Discovery: Blaue LED)&lt;br /&gt;
    GPIOD_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;  //Kein Pull-Up oder Pull-Down Widerstand aktiviert&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Speed = GPIO_Speed_25MHz; //25MHz Update-Rate&lt;br /&gt;
    GPIO_Init(GPIOD, &amp;amp;GPIOD_InitStructure);&lt;br /&gt;
&lt;br /&gt;
    GPIO_SetBits(GPIOD, GPIO_Pin_15);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Einbinden der DSP-Library===&lt;br /&gt;
STM32F3 / STM32F4 Microcontroller haben neben der FPU noch einen Digital-Signal-Processor (DSP). Die DSP dient hauptsächlich dazu, viele Daten schnell zu verarbeiten (z.B. Video- oder Audiosignal). Der CMSIS-Download beinhaltet dazu neben der eigentlichen CMSIS-Library auch noch eine DSP-Library. Diese Library stellt sowohl einfache, mathematische Funktionen wie addieren, multiplizieren usw. als auch komplexe Funktionen, wie z.B  einen IIR-Filter, zur Verfügung. Die DSP-Library ist weiter aufgeteilt in kleinere Module, wie z.B. BasicMathFunctions, FilteringFunctions usw. (siehe &#039;&#039;&#039;&#039;&#039;CMSIS\DSP-Library\Source&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
*1. Source-Dateien des benötigten Moduls zum Projekt hinzufügen. (&#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Add files...&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
*2. &#039;&#039;&#039;&#039;&#039;arm_math.h&#039;&#039;&#039;&#039;&#039; in der &#039;&#039;&#039;&#039;&#039;main.c&#039;&#039;&#039;&#039;&#039; einbinden&lt;br /&gt;
*3. Damit die Warnung &amp;quot;Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)&amp;quot; verschwindet, muss der Define &#039;&#039;&#039;&#039;&#039;__FPU_PRESENT&#039;&#039;&#039;&#039;&#039; hinzugefügt werden. (Keine Ahnung, wieso es die Warnung gibt)&lt;br /&gt;
 &lt;br /&gt;
Jetzt kann die DSP-Library verwedet werden. Das Beispiel multipliziert zwei Buffer miteinander. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
#include &amp;quot;arm_math.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    float32_t x[1024];&lt;br /&gt;
    float32_t y[1024];&lt;br /&gt;
    float32_t z[1024];&lt;br /&gt;
&lt;br /&gt;
    for(uint16_t i = 0; i &amp;lt; 1024; i++)&lt;br /&gt;
    {&lt;br /&gt;
        x[i] = i;&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for(uint16_t i = 0; i &amp;lt; 1024; i++)&lt;br /&gt;
    {&lt;br /&gt;
        y[i] = PI;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    arm_mult_f32(x, y, z, 1024);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Startup-Code, Linker-Script, Takt, FPU usw.==&lt;br /&gt;
===Startup-Code===&lt;br /&gt;
Em::Blocks fügt standardmäßig einen Startup-Code mit in das Projekt ein. Die wichtigsten Dinge die darin erledigt werden sind folgende:&lt;br /&gt;
&lt;br /&gt;
*Stack und Heap wird angelgt&lt;br /&gt;
*Die Vector-Table wird angelegt&lt;br /&gt;
*Ein Default Reset-Handler wird implementiert, dieser erledigt folgende aufgaben:&lt;br /&gt;
**Kopieren der definierten Daten aus dem Flash in den SRAM&lt;br /&gt;
**&#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; wird aufgerfen, wenn &#039;&#039;&#039;&#039;&#039;__NO_SYSTEM_INIT&#039;&#039;&#039;&#039;&#039; nicht definiert ist&lt;br /&gt;
**Sprung in die &#039;&#039;&#039;&#039;&#039;main()&#039;&#039;&#039;&#039;&#039; Funktion&lt;br /&gt;
*Allen anderen Interrupt-Handler wird eine Default-Funktion &#039;&#039;&#039;&#039;&#039;def_irq_handler&#039;&#039;&#039;&#039;&#039; mit einer &#039;&#039;&#039;&#039;&#039;while(1)&#039;&#039;&#039;&#039;&#039;-Schleife zugewiesen, falls kein anderer Interrupt-Handler existiert.&lt;br /&gt;
&lt;br /&gt;
Normalerweise muss am Startup-Code nichts verändert werden.&lt;br /&gt;
&lt;br /&gt;
===Linker-Script===&lt;br /&gt;
Em::Blocks stellt zwei fertige Linker-Scripts bereit, eins für die Ausführung des Programmes aus dem Flash (&#039;&#039;&#039;&#039;&#039;*_flash.ld&#039;&#039;&#039;&#039;&#039;), das andere für die Ausführung aus dem SRAM (&#039;&#039;&#039;&#039;&#039;*_sram.ld&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Normalerweise muss auch hier nichts geändert werden, es sei den Daten sollen in bestimmten Adressbereichen abgelegt werden (z.B. im Core-Coupled RAM), was ich später noch zum Tutorial hinzufüge.&lt;br /&gt;
&lt;br /&gt;
===Der Takt===&lt;br /&gt;
Jeder Controller oder Prozessor braucht einen Takt, indem er die einzelnen Maschinen-Befehle abarbeiten kann.&lt;br /&gt;
Bei den STM32 Mikrocontrollern kann dieser Takt aus verschiedenen Quellen kommen:&lt;br /&gt;
&lt;br /&gt;
1. High Speed Internal Oszillator (HSI)&lt;br /&gt;
&lt;br /&gt;
2. High Speed External Oszillator (HSE)&lt;br /&gt;
&lt;br /&gt;
3. Low Speed Internal Oszillator (LSI)&lt;br /&gt;
&lt;br /&gt;
4. Low Speed External Oszillator (LSE)&lt;br /&gt;
&lt;br /&gt;
5. Phase-Locked Loop (PLL) (generiert den Takt aus den ersten vier Taktquellen durch Teiler und Faktoren)&lt;br /&gt;
&lt;br /&gt;
Nach einem Reset wird der Controller aus der HSI Taktquelle versorgt (16MHz beim STM32F407VG). Um die voll Performance des Controllers zu erreichen muss die PLL verwendet werden, welche den Takt durch geschickte Teiler und Faktoren vervielfältigt, sodass am Ende der Controller mit der maximalen Taktfrequenz läuft. Die notwendige Initialisierung der PLL findet in der Funktion &#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; statt. Die PLL erzeugt zunächst einen Basistakt:&lt;br /&gt;
&lt;br /&gt;
PLL_VCO = (F_HSE / PLL_M) * PLL_N&lt;br /&gt;
&lt;br /&gt;
Aus diesem Takt wird dann der Takt für den Controller-Kern abgeleitet:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = PLL_VCO / PLL_P&lt;br /&gt;
&lt;br /&gt;
Und der Takt für SDIO / USB / RNG (48MHz):&lt;br /&gt;
&lt;br /&gt;
48MHz = PLL_VCO / PLL_Q&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Durch weiter Teiler werden, die Takte für die einzelnen Busse erzeugt, da diese nicht alle beliebig schnell betrieben werden dürfen.&lt;br /&gt;
&lt;br /&gt;
Genaue Angaben findet man zu dem jeweiligen Clock-System des Controllers im Reference Manual.&lt;br /&gt;
&lt;br /&gt;
Ein Blick in den &amp;quot;Kommentar-Header&amp;quot; verrät, dass von einem externen (HSE) Oszillator von 25MHz ausgegangen wird, der die PLL versorgen soll.&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((25MHz / PLL_M(25)) * PLL_N(336)) / PLL_P(2) = 168MHz&lt;br /&gt;
&lt;br /&gt;
Allerdings stimmt diese Rechnung natürlich nur, wenn wirklich ein 25MHz Quarz am Controller angeschlossen ist. Auf dem STM32F4-Discovery Board befindet sich aber nur ein 8MHz Quarz. Demnach gilt:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((8MHz / PLL_M(25)) * PLL_N(336)) / PLL_P(2) = 53.76MHz&lt;br /&gt;
&lt;br /&gt;
Der Controller läuft also nur mit 53.76MHz, wenn wie ober beschrieben ein Projekt erstellt wird. Allerdings kann dieses Problem durch ändern von den betroffen Defines behoben werden:&lt;br /&gt;
 &lt;br /&gt;
*Dazu geht man in die &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; Datei und passt zur Vollständigkeit erstmal die zum Controller passende Tabelle im &amp;quot;Kommentar-Header&amp;quot; an (Z.57f):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      HSE Frequency(Hz)                      | 8000000&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      PLL_M                                  | 8&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Danach passt man den PPL_M Define (Z.254) an:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/************************* PLL Parameters *************************************/&lt;br /&gt;
/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */&lt;br /&gt;
#define PLL_M      8&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Außerdem muss man den HSE_VALUE Define in der &#039;&#039;&#039;&#039;&#039;inc/stm32f4xx.h&#039;&#039;&#039;&#039;&#039; angepasst werden (Z.122):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#if !defined  (HSE_VALUE)&lt;br /&gt;
  #define HSE_VALUE    ((uint32_t)8000000) /*!&amp;lt; Value of the External oscillator in Hz */&lt;br /&gt;
&lt;br /&gt;
#endif /* HSE_VALUE */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine neue Berechnung zeigt:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((8MHz / PLL_M(8)) * PLL_N(336)) / PLL_P(2) = 168MHz&lt;br /&gt;
&lt;br /&gt;
Jetzt läuft der Controller mit maximaler Geschwindigkeit.&lt;br /&gt;
&lt;br /&gt;
Die Theorie wird durch folgendes Programm verifiziert. Der geviertelte System-Takt SYSCLK wir am Pin PC9 ausgegeben. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);&lt;br /&gt;
&lt;br /&gt;
    GPIO_InitTypeDef GPIOC_InitStructure;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Mode = GPIO_Mode_AF;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_OType = GPIO_OType_PP;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Pin = GPIO_Pin_9;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;&lt;br /&gt;
    GPIO_Init(GPIOC, &amp;amp;GPIOC_InitStructure);&lt;br /&gt;
&lt;br /&gt;
    RCC_MCO2Config(RCC_MCO2Source_SYSCLK, RCC_MCO2Div_4);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Die FPU===&lt;br /&gt;
====Allgemeines====&lt;br /&gt;
STM32F3 und STM32F4 Controller haben eine FPU.&lt;br /&gt;
Damit die FPU richtig verwendet wird, müssen normalerweise zwei Bedingungen erfüllt sein:&lt;br /&gt;
&lt;br /&gt;
1. Der Controller muss die FPU Hardware-seitig aktivieren&lt;br /&gt;
&lt;br /&gt;
2. Damit die FPU auch was zu tuen bekommt, müssen vom Compiler FPU-Instructions erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
Die Em::Blocks IDE verwendet standardmäßig die FPU, wenn eine Vorhanden ist. Hier wird die FPU Hardware-seitig aktiviert (&#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; Z.341):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* FPU settings ------------------------------------------------------------*/&lt;br /&gt;
  #if (__FPU_PRESENT == 1) &amp;amp;&amp;amp; (__FPU_USED == 1)&lt;br /&gt;
    SCB-&amp;gt;CPACR |= ((3UL &amp;lt;&amp;lt; 10*2)|(3UL &amp;lt;&amp;lt; 11*2));  /* set CP10 and CP11 Full Access */&lt;br /&gt;
  #endif&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
__FPU_PRESENT wird in der &#039;&#039;&#039;&#039;&#039;stm32f4xx.h&#039;&#039;&#039;&#039;&#039; definiert.&lt;br /&gt;
__FPU_USED wird von der IDE übernommen (siehe Build-Log): &#039;&#039;&#039;&#039;&#039;-D__FPU_USED&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Außerdem wird der Compiler von der IDE standardmäßig mit dem Argument &#039;&#039;&#039;&#039;&#039;-mfloat-abi=hard&#039;&#039;&#039;&#039;&#039; aufgerufen, wodurch FPU-Instructions erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
====FPU abschalten====&lt;br /&gt;
Um die FPU ab zu schalten (Mir würde jetzt nur Strom sparen als Grund einfallen) geht man wie folgt vor:&lt;br /&gt;
&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; Device -&amp;gt; Policy&#039;&#039;&#039;&#039;&#039; wählt man &#039;&#039;&#039;&#039;&#039;Use target settings&#039;&#039;&#039;&#039;&#039; und über nimmt die Einstellungen, die vorher dort eingetragen waren, allerdings lässt man das Feld &#039;&#039;&#039;&#039;&#039;FP-hardware&#039;&#039;&#039;&#039;&#039; frei.&lt;br /&gt;
&lt;br /&gt;
[[Datei:fpu_1.png|FPU Abschalten Schritt 1]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;Compiler Settings -&amp;gt; Policy&#039;&#039;&#039;&#039;&#039; wählt man dann &#039;&#039;&#039;&#039;&#039;Use target options only&#039;&#039;&#039;&#039;&#039;. Dann kann man unter &#039;&#039;&#039;&#039;&#039;Categories&#039;&#039;&#039;&#039;&#039; die Option &#039;&#039;&#039;&#039;&#039;ARM FPU architecture&#039;&#039;&#039;&#039;&#039; auswählen. Dort stehen dann drei Möglichkeiten für die FPU zur Verfügung:&lt;br /&gt;
&lt;br /&gt;
1. Software-FPU-Library für Gleitkomma-Berechnung verwenden - Keine FPU-Instructions werden generiert (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=soft&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
2. Eine Mischung aus Software- und Hardware-FPU wird verwendet (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=softfp&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
3. Hardware-FPU wird für Gleitkomma-Berechnungen verwendet (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=hard&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
[[Datei:fpu_2.png|FPU Abschalten Schritt 2]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Um die FPU ab zu schalten wählt man natürlich die erste Möglichkeit.&lt;br /&gt;
Bei der 2. und 3. Möglichkeit fügt die IDE auch den Define &#039;&#039;&#039;&#039;&#039;__FPU_USED&#039;&#039;&#039;&#039;&#039; hinzu. Bei Der ersten Möglichkeit nicht. Der Code muss also nicht verändert / auskommentiert werden.&lt;br /&gt;
&lt;br /&gt;
Um die FPU wieder zu aktivieren müssen alle Schritte wieder rückgängig gemacht werden.&lt;br /&gt;
&lt;br /&gt;
Am besten ist es einfach mal alle Möglichkeiten im Einzelschritt durch zu probieren. Dann stellt man schnell fest, ob die FPU aktiviert wir oder nicht. Ein Blick in den erweiterten &#039;&#039;&#039;&#039;&#039;Build-Log&#039;&#039;&#039;&#039;&#039; gibt auch schnell Aufschluss darüber, wie der Compiler aufgerufen wird (siehe Kapitel [http://www.mikrocontroller.net/articles/STM32_-_Einstieg_mit_Em::Blocks#Compilieren Compilieren]).&lt;br /&gt;
&lt;br /&gt;
====Test Programm für die FPU====&lt;br /&gt;
Hier ein kleines Testprogramm, dass misst wie viele Taktzyklen für eine Gleitkomma-Multiplikation gebraucht werden. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define CORE_SysTickEn()    (*((u32*)0xE0001000)) = 0x40000001&lt;br /&gt;
#define CORE_SysTickDis()   (*((u32*)0xE0001000)) = 0x40000000&lt;br /&gt;
#define CORE_GetSysTick()   (*((u32*)0xE0001004))&lt;br /&gt;
&lt;br /&gt;
uint32_t t1, t2, dt;&lt;br /&gt;
float x, y, z;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    x = 53.64f;&lt;br /&gt;
    y = 0.27f;&lt;br /&gt;
&lt;br /&gt;
    CORE_SysTickEn();&lt;br /&gt;
    t1 = CORE_GetSysTick();&lt;br /&gt;
&lt;br /&gt;
    z = x * y;&lt;br /&gt;
&lt;br /&gt;
    t2 = CORE_GetSysTick();&lt;br /&gt;
    CORE_SysTickDis();&lt;br /&gt;
&lt;br /&gt;
    dt = (t2 - t1) - 9; //9 Takt-Zyklen werden für die Messung gebraucht &lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Booten aus dem SRAM==&lt;br /&gt;
STM32 Controller haben die Möglichkeit Code aus dem Flash als auch aus dem SRAM auszuführen. Um eine Anwenung per Debugger in des SRAM zu laden sind nur wenige Schritte erforderlich:&lt;br /&gt;
&lt;br /&gt;
*Um das Linkerscript für den SRAM zu verwenden geht man zu: &#039;&#039;&#039;&#039;&#039;Build options... -&amp;gt; Device&#039;&#039;&#039;&#039;&#039; dort wählt man unter &#039;&#039;&#039;&#039;&#039;Policy&#039;&#039;&#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;Use target settings&#039;&#039;&#039;&#039;&#039; aus und übernimmt die vorherigen Einstellungen, nur unter &#039;&#039;&#039;&#039;&#039;Linker script*&#039;&#039;&#039;&#039;&#039; gibt man &#039;&#039;&#039;&#039;&#039;.\stm32f407vg_sram.ld&#039;&#039;&#039;&#039;&#039; an&lt;br /&gt;
&lt;br /&gt;
*Dann muss man noch unter &#039;&#039;&#039;&#039;&#039;Debug -&amp;gt; Interfaces -&amp;gt; Settings&#039;&#039;&#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;Vector table start&#039;&#039;&#039;&#039;&#039; auf 0x20000000 ändern und &#039;&#039;&#039;&#039;&#039;Execute from RAM&#039;&#039;&#039;&#039;&#039; auswählen.&lt;br /&gt;
&lt;br /&gt;
Anschließend kann man die Anwendung ganz normal debuggen. Nach einem Reset muss die Anwenung erneut mit dem Debugger gestartet werden.&lt;br /&gt;
&lt;br /&gt;
=Fortsetzung folgt..=&lt;br /&gt;
Kritik, Wünsche usw. sind gerne erwünscht, am besten hier in den Thread posten: [http://www.mikrocontroller.net/topic/323750 Neues STM32 Tutorial]&lt;br /&gt;
&lt;br /&gt;
[[Category:ARM]]&lt;br /&gt;
[[Category:STM32]]&lt;/div&gt;</summary>
		<author><name>Avrprogger</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=STM32_-_Einstieg_mit_Em::Blocks&amp;diff=81568</id>
		<title>STM32 - Einstieg mit Em::Blocks</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=STM32_-_Einstieg_mit_Em::Blocks&amp;diff=81568"/>
		<updated>2014-02-13T14:13:39Z</updated>

		<summary type="html">&lt;p&gt;Avrprogger: dfg&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In diesem Tutorial werde ich versuchen, möglichst einfach, die ersten Schritte zur Entwicklung von STM32 Anwenungen mit der Em::Blocks IDE zu erklären. Hier soll nicht so stark auf die einzelnen Peripherie-Module der Controller eingegangen werden, sondern mehr auf die IDE und die verschieden Libraries, wie die CMSIS Library, die DSP-Library, die Standard-Peripheral-Library, die USB-Library und vllt. über Ethernet. Ich denke ein Kapitel zu FreeRTOS wird es auch geben. Auserdem steht im Vordergrund Sachen wie z.B. booten aus dem SRAM, In-Application-Programming, FPU, Core-Coupled-RAM usw. Mal sehn wie weit ich komme ;)&lt;br /&gt;
&lt;br /&gt;
==Die Entwicklungsumgebung==&lt;br /&gt;
===Hardware===&lt;br /&gt;
Zum testen der Anwendungen, benutze ich das STM32F4-Discovery Board, welches einen Debugger, Peripherie und natürlich einen STM32 Controller (STM32F407VGT6) enthält. Deshalb sind alle Beispiele hier für den STM32F407VG Controller ausgelegt, können aber meisten 1:1 auf andere Controller portiert werden. Ich werde auch möglichsts keine STM32F4-Discovery Board spezifischen Libraries verwenden, damit der Portierungs-Vorgang möglichsts einfach bleibt.&lt;br /&gt;
&lt;br /&gt;
===Software===&lt;br /&gt;
In diesem Tutorial verwende ich [http://www.emblocks.org/ Em::Blocks] als IDE. Em::Blocks ist eine kostenlose, uneingeschränkte IDE, die alle STM32 Mikrcontroller unterstützt und sehr einfach zu bedienen ist.&lt;br /&gt;
nach dem Download kann die IDE per Dialog, sehr einfach, installiert werden. Als Compiler beinhaltet Em::Blocks den &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
Die IDE unterstützt zurzeit den ST-Link, den J-Link und es gibt eine Generic-Vorlage, durch welche andere Debugger konfiguriert werden können.&lt;br /&gt;
&lt;br /&gt;
Außerdem muss noch der passende Treiber für den Debugger installiert werden. Verwendet man ein Discovery-Board muss der [http://www.st.com/web/catalog/tools/FM146/CL1984/SC724/SS1677/PF251168 ST-Link/V2]-Treiber heruntergeladen und installiert werden. (Die Installation muss evtl. als Administrator ausgeführt werden, da sonst die Installation unvollständig wird.) Nach der Installation des Treibers kann man den Debugger über die entsprechende USB Schnittstelle an den PC anschließen und es sollte die Meldung von Windows kommen, dass der richtige Treiber gefunden wurde.&lt;br /&gt;
&lt;br /&gt;
===Libraries===&lt;br /&gt;
Zum programmieren benötigt man noch die [http://www.arm.com/products/processors/cortex-m/cortex-microcontroller-software-interface-standard.php CMSIS] und die Standard-Peripheral-Library (z.B. für die F4 Controller [http://www.st.com/stonline/stappl/productcatalog/app?page=partNumberSearchPage&amp;amp;levelid=SS1577&amp;amp;parentid=1743&amp;amp;resourcetype=SW Standard-Peripheral-Library-F4]), die man am besten in einen Ordner (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\STM32&#039;&#039;&#039;&#039;&#039;) entpackt&lt;br /&gt;
&lt;br /&gt;
==Basis-Wissen zur IDE==&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von Dateien zum Projekt===&lt;br /&gt;
Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf &amp;lt;ProjektName&amp;gt; -&amp;gt; Add files...&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Enfernen von Dateien aus dem Projekt===&lt;br /&gt;
Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf die Datei / mehrere Dateien auswählen -&amp;gt; Remove file from project&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
Die Dateien werden lediglich aus dem Projekt entfernt und nicht von der Festplatte gelöscht.&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von Include-Pfaden===&lt;br /&gt;
Sofern die Include-Datei(en) nicht im standard Include-Ordner &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; des Projektes liegen, muss man den Pfad zum Projekt hinzufügen, damit der Compiler die Include-Dateien später auch finden kann. Man geht wie folgt vor: Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; Search Directories -&amp;gt; Add&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von globalen Defines zum Build===&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; #defines&#039;&#039;&#039;&#039;&#039; können globale Defines hinzugefügt werden.&lt;br /&gt;
&lt;br /&gt;
===Compilieren===&lt;br /&gt;
Entweder über das &#039;&#039;&#039;&#039;&#039;Build&#039;&#039;&#039;&#039;&#039; Menü oder über &#039;&#039;&#039;&#039;&#039;F7&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Um eine genau Ausgabe des Compiler-Aufrufes mit allen Argumenten zu bekommen, geht man im &#039;&#039;&#039;&#039;&#039;Settings&#039;&#039;&#039;&#039;&#039; Menü auf &#039;&#039;&#039;&#039;&#039;Tools...&#039;&#039;&#039;&#039;&#039; und dann auf &#039;&#039;&#039;&#039;&#039;Toolchain executables&#039;&#039;&#039;&#039;&#039;. Ganz unten, unter &#039;&#039;&#039;&#039;&#039;Logging&#039;&#039;&#039;&#039;&#039; kann man dann &#039;&#039;&#039;&#039;&#039;Full command line&#039;&#039;&#039;&#039;&#039; auswählen.&lt;br /&gt;
&lt;br /&gt;
====Compiler Optionen====&lt;br /&gt;
=====Optimierung=====&lt;br /&gt;
Standardmäßig verwendet Em::Blocks keine Optimierung. Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; Categories: Optimization&#039;&#039;&#039;&#039;&#039; kann zwischen verschieden Optimierungen ausgewählt werden.&lt;br /&gt;
&lt;br /&gt;
=====Verschiedene C-Standards=====&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; Categories: Language standard&#039;&#039;&#039;&#039;&#039; kann man zwischen verschieden C-Standard auswählen, wie z.B, C99.&lt;br /&gt;
(Mit C99 können auch die Lauf-Variable in der for-Schleife deklariert werden: for(int i;..))&lt;br /&gt;
&lt;br /&gt;
===Debuggen===&lt;br /&gt;
*Als erstes den Debugger starten über das &#039;&#039;&#039;&#039;&#039;Debug&#039;&#039;&#039;&#039;&#039; Menü und &#039;&#039;&#039;&#039;&#039;Start/stop Debug Session&#039;&#039;&#039;&#039;&#039; oder über &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
*Danach läuft die Anwendung auf dem Controller und warten im &#039;&#039;&#039;&#039;&#039;Reset_Handler&#039;&#039;&#039;&#039;&#039; auf Einzelschritt- bzw. Run- Befehle (&#039;&#039;&#039;&#039;&#039;F5, F10, F11&#039;&#039;&#039;&#039;&#039; usw..(siehe &#039;&#039;&#039;&#039;&#039;Debug-Menü&#039;&#039;&#039;&#039;&#039; für alle Möglichkeiten))&lt;br /&gt;
&lt;br /&gt;
*Mit &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039; wird die Debug-Session auch wieder beendet&lt;br /&gt;
&lt;br /&gt;
*Unter &#039;&#039;&#039;&#039;&#039;Debug -&amp;gt; Interfaces -&amp;gt; Target settings&#039;&#039;&#039;&#039;&#039; können Eigenschaften, wie z.B &#039;&#039;&#039;&#039;&#039;Run to main()&#039;&#039;&#039;&#039;&#039; aktiviert werden.&lt;br /&gt;
&lt;br /&gt;
===Projekt als Template abspeichern===&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;File -&amp;gt; Save project as template...&#039;&#039;&#039;&#039;&#039;. Das Template erscheint dann im Projekt-Dialog unter &#039;&#039;&#039;&#039;&#039;User templates&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Das erste Projekt erstellen==&lt;br /&gt;
Hier erkläre ich, wie man am Besten (aus meiner Sicht), ein neues Projekt von Grund auf erstellt, sodass man hinterher, den Controller-Kern über die CMSIS-Library und die Peripherie über die Register steuern kann.&lt;br /&gt;
&lt;br /&gt;
===1. Projekt mit der IDE erstellen===&lt;br /&gt;
Nach der Installation der oben beschriebenen Komponenten erstellt man am besten ein Verzeichnis (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\EmBlocks&#039;&#039;&#039;&#039;&#039;), indem später alle Projekte gespeichert werden. Für Libraries kann man auch noch ein Verzeichnis (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\STM32&#039;&#039;&#039;&#039;&#039;) erstellen, wo alle Libraries gespeichert werden, die man für die Projekt brauchen.&lt;br /&gt;
&lt;br /&gt;
Als nächstes starten man EmBlocks. Bei dem ersten Start öffnet sich ein Fenster, wo verschiedene Compiler angezeigt werden, die Em::Blocks findet. Dort wählt man den &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039; aus und klickt &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039;. Nun sollte sich das Hauptfenster von Em::Blocks öffnen. Über &#039;&#039;&#039;&#039;&#039;Create a new Project&#039;&#039;&#039;&#039;&#039; oder &#039;&#039;&#039;&#039;&#039;File -&amp;gt; New -&amp;gt; Project&#039;&#039;&#039;&#039;&#039; ruft man den Projekt-Dialog auf und kann ein neues Projekt erzeugen.&lt;br /&gt;
&lt;br /&gt;
Auf der Ersten Seite wählen man den &#039;&#039;&#039;&#039;&#039;STmicro-ARM&#039;&#039;&#039;&#039;&#039; Projekt-Typ aus.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_1.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auf der nächsten Seite wird man darauf hingewiesen, dass das der entsprechende Projekt-Typ-Dialog ausgeführt wird. Hier kann man ein Häkchen bei &#039;&#039;&#039;&#039;&#039;Skip this page next time&#039;&#039;&#039;&#039;&#039; setzen und auf &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; klicken.&lt;br /&gt;
&lt;br /&gt;
Im nächsten Schritt wählen man das zuvor erstellt Verzeichnis unter &#039;&#039;&#039;&#039;&#039;Folder to create Project in&#039;&#039;&#039;&#039;&#039; aus, indem später alle Projekt gespeichert werden. Außerdem geben wir dem Projekt einen Namen (z.B. &#039;&#039;&#039;&#039;&#039;FirstProject&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_2.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danach muss man einen Compiler auswählen und bestimmen, welche Projekt-Konfigurationen erszeugt werden sollen. Unter &#039;&#039;&#039;&#039;&#039;Compiler&#039;&#039;&#039;&#039;&#039; wählt man &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039; und man kann das Häkchen bei &#039;&#039;&#039;&#039;&#039;Create &amp;quot;Release&amp;quot; configuration&#039;&#039;&#039;&#039;&#039; entfernen, da diese unnötig ist, die Debug-Konfiguration sollte eig. immer ausreichen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_3.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auf den folgenden Seite wird der Controller ausgewählt. Verwendet man ein STM32F4-Discovery Board müssen folgende Dinge gewählt werden: &#039;&#039;&#039;&#039;&#039;Cortex_M4 (F3xx - F4xx) -&amp;gt; STM32F4xx (Cortex M4 with FPU) -&amp;gt; STM32F407VG&#039;&#039;&#039;&#039;&#039;. Leider sind die Auswahl Möglichkeiten nicht ganz richtig, da auch die F3 Controller einen Cortex M4 Kern und eine FPU haben (Ist aber nicht so wichtig, ist nur eine formale Sache). Außerdem entfernt man das Häkchen bei &#039;&#039;&#039;&#039;&#039;Standard Peripherals Library&#039;&#039;&#039;&#039;&#039; (Wie man die Standard-Peripheral-Library einbindet und verwendet erkläre ich später). Man kann auch das Häkchen bei &#039;&#039;&#039;&#039;&#039;Create hex file for Realease target&#039;&#039;&#039;&#039;&#039; entfernen.&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;Stack Size&#039;&#039;&#039;&#039;&#039; und &#039;&#039;&#039;&#039;&#039;Heap Size&#039;&#039;&#039;&#039;&#039; wird die Größe von Stack und Heap festgelegt. Für eine erste Anwendung kann man die Einstellungen so lassen (Stack-Size: 0x0100 =&amp;gt; 256 Byte Stack und Heap-Size: 0x0000 =&amp;gt; kein Heap). Mit &#039;&#039;&#039;&#039;&#039;Finish&#039;&#039;&#039;&#039;&#039; ist der Projekt Dialog abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_4.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danach sollten sich zwei neue Fenster öffnen, um die Debug-Eigenschaften fest zu legen.&lt;br /&gt;
Verwendet man ein Discovery Board/ST-Link müssen die Einstellungen wie auf dem Bild gewählt werden. Über den Button &#039;&#039;&#039;&#039;&#039;Settings&#039;&#039;&#039;&#039;&#039; öffnet sich das zweite Fenster, falls sich dieses nicht schon von alleine öffnen sollte. Nach den Schließen der Fenster über &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; ist der Projekt Dialog beendet und ein neues Projekt steht zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_5_1.png|Debug Eigenschaften 1. Fenster]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_5_2.png|Debug Eigenschaften 2. Fenster]]&lt;br /&gt;
&lt;br /&gt;
===2. CMSIS-Library und Startup-Code hinzufügen===&lt;br /&gt;
Wenn man sich, nachdem man ein neues Projekt in der IDE erstellt hat, die bereits vorhandenen Dateien im Projekt ansieht, stellt man fest, das bereits ein Ordner &#039;&#039;&#039;&#039;&#039;cmsis&#039;&#039;&#039;&#039;&#039; existiert, der einige wichtige Include-Dateien der CMSIS-Library enthält. Allerdings sind das wirklich nur die wichtigsten Include-Dateien der CMSIS-Library und dazu noch, die aus einer älternen Version. Ich ziehe es deshalb vor die &amp;quot;Mini-CMSIS-Libraray&amp;quot; und die &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c/.h&#039;&#039;&#039;&#039;&#039; Dateien des Projektes durch aktuellere Versionen zu ersetzen. So ist später auch die Integration  von anderen Libraries, wie z.B. der CMSIS-DSP-Libarary einfacher.  &lt;br /&gt;
&lt;br /&gt;
Zunächst gehen man in das Projekt-Verzeichnis und löscht:&lt;br /&gt;
*Den Ordner &#039;&#039;&#039;&#039;&#039;cmsis&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Alle Dateien im Include Verzeichnis &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; im &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner&lt;br /&gt;
&lt;br /&gt;
Außerdem entfernt man auch alle gelöschten Dateien in der IDE aus dem Projekt mit &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Rechts Klick -&amp;gt; Remove file from project&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Es sollte folgende Verzeichnis Struktur überbleiben:&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_6.png|Überbleibende Dateien]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Jetzt müssen die gelöschten Dateien durch die aktuelleren ersetzt werden.&lt;br /&gt;
&lt;br /&gt;
*Dazu kopieren man den gesamten Ordner &#039;&#039;&#039;&#039;&#039;CMSIS&#039;&#039;&#039;&#039;&#039; aus dem CMSIS Download in das Projekt Verzeichnis.&lt;br /&gt;
&lt;br /&gt;
*Aus dem Standard-Peripheral-Library Download kopiert man von &#039;&#039;&#039;&#039;&#039;Libraries\CMSIS\Device\ST\STM32F4xx\Include&#039;&#039;&#039;&#039;&#039; alle Dateien in den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projekt Verzeichnisses&lt;br /&gt;
&lt;br /&gt;
*Aus der Standard-Peripheral-Library kopieren man ebenfalls von &#039;&#039;&#039;&#039;&#039;Libraries\CMSIS\Device\ST\STM32F4xx\Source\Templates&#039;&#039;&#039;&#039;&#039; die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; in den &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner des Projekts&lt;br /&gt;
&lt;br /&gt;
Anschließend müssen die neuen Dateien in der IDE dem Projekt hinzugefügt werden. Dazu benutzt man &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Rechts Klick -&amp;gt; Add files&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
*Aus dem &#039;&#039;&#039;&#039;&#039;CMSIS&#039;&#039;&#039;&#039;&#039; Ordner im Projekt Verzeichnis werden aus den Unterorder &#039;&#039;&#039;&#039;&#039;Include&#039;&#039;&#039;&#039;&#039; folgende Dateien dem Projekt hinzugefügt:&lt;br /&gt;
**arm_common_tables.h&lt;br /&gt;
**arm_const_structs.h&lt;br /&gt;
**arm_math.h&lt;br /&gt;
**core_cm4.h&lt;br /&gt;
**core_cm4_simd.h&lt;br /&gt;
**core_cmFunc.h&lt;br /&gt;
**core_cmInstr.h&lt;br /&gt;
*Alle Dateien aus den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projektes&lt;br /&gt;
*Die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; aus dem &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner&lt;br /&gt;
&lt;br /&gt;
So sollte die Struktur dann aussehen:&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_7.png|Anwenungs-Grundgerüst]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Da einige Dateien der Libraries später bearbeitet werden müssen und Schreibgeschützt sind, weise ich hier schonmal darauf hin, das der Schreibschutz in der IDE über &#039;&#039;&#039;&#039;&#039;Rechts Klick auf die Datei -&amp;gt; Properties -&amp;gt; Häkchen bei &amp;quot;File is read only&amp;quot; entfernen&#039;&#039;&#039;&#039;&#039; entfert werden kann.&lt;br /&gt;
&lt;br /&gt;
Damit die IDE die Header-Dateien der CMSIS Library auch finden kann, weil diese ja nicht im standard Include Ordner &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; liegen, muss unter &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Build Options -&amp;gt; Search Directories&#039;&#039;&#039;&#039;&#039; der Pfad &#039;&#039;&#039;&#039;&#039;CMSIS\Include&#039;&#039;&#039;&#039;&#039; hinzugefügt werden.&lt;br /&gt;
&lt;br /&gt;
Compiliert man jetzt das Projekt mit &#039;&#039;&#039;&#039;&#039;F7&#039;&#039;&#039;&#039;&#039; gibt es ein paar Fehler Meldungen, weil keine Controller-Reihe ausgewählt wurde. Ebenfalls unter &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Build Options -&amp;gt; Compiler Settings -&amp;gt; #defines&#039;&#039;&#039;&#039;&#039; wird der Define &#039;&#039;&#039;&#039;&#039;STM32F40_41xxx&#039;&#039;&#039;&#039;&#039; hinzugefügt.&lt;br /&gt;
&lt;br /&gt;
Beim erneuten Compilieren sollten sich nun keine neuen Fehler ergeben.&lt;br /&gt;
&lt;br /&gt;
===3. Das erste Programm===&lt;br /&gt;
Nachdem ein grundsätzliches &amp;quot;Gerüst&amp;quot; fertig ist, kann man den ersten Code schreiben.&lt;br /&gt;
main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC-&amp;gt;AHB1ENR |= RCC_AHB1ENR_GPIODEN;    //Takt für GPIO aktivieren&lt;br /&gt;
    GPIOD-&amp;gt;MODER |= GPIO_MODER_MODER15_0;   //GPIOD Pin15 als Ausgang&lt;br /&gt;
    GPIOD-&amp;gt;BSRRL |= GPIO_BSRR_BS_15;        //GPIOD Pin15 auf High ziehen&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039; wird dann der Debugger gestartet. Hat der Debugger das Projekt erfolgreich übertragen kann die Ausführung mit &#039;&#039;&#039;&#039;&#039;F5&#039;&#039;&#039;&#039;&#039; begonnen werden.&lt;br /&gt;
&lt;br /&gt;
==Libraries einbinden/verwenden==&lt;br /&gt;
Um Libraries, wie hier im Tutorial, einzubinden, wird ein existierendes Projekt, wie ein im Kapitel [http://www.mikrocontroller.net/articles/STM32_-_Einstieg_mit_Em::Blocks#Das_erste_Projekt_erstellen Das Erste Projekt erstellen] beschrieben wird, vorausgesetzt.&lt;br /&gt;
&lt;br /&gt;
===Einbinden der Standard-Peripheral-Library===&lt;br /&gt;
Um nicht immer die einzelnen Register, wie im ersten &amp;quot;bare-metal&amp;quot; Beispiel, aus dem Reference-Manual zu suchen und zu beschreiben, gibt es von ST die Standard Peripheral Library, die diese Aufgaben übernimmt und mit der sich die &amp;quot;normale/grundlegende&amp;quot; (Alles außer USB und Ethernet) Peripherie recht einfach steuern lässt. Ich kopiere die Standard-Peripheral-Library immer per Hand in das Projekt. Darduch hat man auch gleich die aktuellste Version (in den älteren Version gibt es einige Bugs). &lt;br /&gt;
&lt;br /&gt;
*1. Den Ordner &#039;&#039;&#039;&#039;&#039;Libraries\STM32F4xx_StdPeriph_Driver&#039;&#039;&#039;&#039;&#039; aus dem Standard-Peripheral-Library Download in das Projekt-Verzeichnis kopieren&lt;br /&gt;
*2. Die Datei &#039;&#039;&#039;&#039;&#039;Project\STM32F4xx_StdPeriph_Templates\stm32f4xx_conf.h&#039;&#039;&#039;&#039;&#039; ebenfalls aus dem Standard-Peripheral-Library Download in den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projektes kopieren.&lt;br /&gt;
*3. In der IDE den Include-Path &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\inc&#039;&#039;&#039;&#039;&#039; hinzufügen&lt;br /&gt;
*4. Und das/den Define &#039;&#039;&#039;&#039;&#039;USE_STDPERIPH_DRIVER&#039;&#039;&#039;&#039;&#039; hinzufügen&lt;br /&gt;
*4. Source- und Include-Dateien zum Projekt hinzufügen&lt;br /&gt;
**Achtung: Es dürfen nur die Dateien hinzugefügt werden, für die der Controller auch die entsprechende Peripherie bereit stellt. Diese Dateien dürfen nicht beim STM32F4-Discovery/STM32F407VG hinzugefügt werden.&lt;br /&gt;
***stm32f4xx_dma2d.c/.h&lt;br /&gt;
***stm32f4xx_fmc.c/.h&lt;br /&gt;
***stm32f4xx_ltdc.c/.h&lt;br /&gt;
***stm32f4xx_sai.c/.h&lt;br /&gt;
&lt;br /&gt;
Daraus resultiert folgende Struktur:&lt;br /&gt;
&lt;br /&gt;
[[Datei:stdperiphlib_2.png|Header-Struktur]] [[Datei:stdperiphlib_1.png|Source-Struktur]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Anschließen kann die Standard-Peripheral-Library benutz werden.&lt;br /&gt;
main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);&lt;br /&gt;
&lt;br /&gt;
    GPIO_InitTypeDef GPIOD_InitStructure;&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Mode = GPIO_Mode_OUT;     //Als Ausgang&lt;br /&gt;
    GPIOD_InitStructure.GPIO_OType = GPIO_OType_PP;    //Push-Pull Betrieb&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Pin = GPIO_Pin_15;        //Pin 15 (STM32F4-Discovery: Blaue LED)&lt;br /&gt;
    GPIOD_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;  //Kein Pull-Up oder Pull-Down Widerstand aktiviert&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Speed = GPIO_Speed_25MHz; //25MHz Update-Rate&lt;br /&gt;
    GPIO_Init(GPIOD, &amp;amp;GPIOD_InitStructure);&lt;br /&gt;
&lt;br /&gt;
    GPIO_SetBits(GPIOD, GPIO_Pin_15);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Einbinden der DSP-Library===&lt;br /&gt;
STM32F3 / STM32F4 Microcontroller haben neben der FPU noch einen Digital-Signal-Processor (DSP). Die DSP dient hauptsächlich dazu, viele Daten schnell zu verarbeiten (z.B. Video- oder Audiosignal). Der CMSIS-Download beinhaltet dazu neben der eigentlichen CMSIS-Library auch noch eine DSP-Library. Diese Library stellt sowohl einfache, mathematische Funktionen wie addieren, multiplizieren usw. als auch komplexe Funktionen, wie z.B  einen IIR-Filter, zur Verfügung. Die DSP-Library ist weiter aufgeteilt in kleinere Module, wie z.B. BasicMathFunctions, FilteringFunctions usw. (siehe &#039;&#039;&#039;&#039;&#039;CMSIS\DSP-Library\Source&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
Um die DSP-Library zu verwenden müssen nur die Source-Files des benötigten Moduls einbinden.&lt;br /&gt;
(&#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Add files...&#039;&#039;&#039;&#039;&#039;). Außerdem muss in der &#039;&#039;&#039;&#039;&#039;main.c&#039;&#039;&#039;&#039;&#039; der Include &#039;&#039;&#039;&#039;&#039;arm_math.h&#039;&#039;&#039;&#039;&#039; eingebunden werden. Aus irgendeinem Grund gibt es dann jedoch die Warnung: &amp;quot;Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)&amp;quot;. Ich hab noch nicht rausgefunden, wieso diese Warnung auftaucht. Die Warnung verschwindet, wenn man in der &#039;&#039;&#039;&#039;&#039;Build options...&#039;&#039;&#039;&#039;&#039; das Define &#039;&#039;&#039;&#039;&#039;__FPU_PRESENT&#039;&#039;&#039;&#039;&#039; hinzufügt (Ich weiß selber das das keine schöne Lösung ist, eine andere hab ich jedoch noch nicht gefunden). Jetzt kann die DSP-Library verwedet werden. Das Beispiel multipliziert zwei Buffer miteinander. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
#include &amp;quot;arm_math.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    float32_t x[1024];&lt;br /&gt;
    float32_t y[1024];&lt;br /&gt;
    float32_t z[1024];&lt;br /&gt;
&lt;br /&gt;
    for(uint16_t i = 0; i &amp;lt; 1024; i++)&lt;br /&gt;
    {&lt;br /&gt;
        x[i] = i;&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for(uint16_t i = 0; i &amp;lt; 1024; i++)&lt;br /&gt;
    {&lt;br /&gt;
        y[i] = PI;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    arm_mult_f32(x, y, z, 1024);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Startup-Code, Linker-Script, Takt, FPU usw.==&lt;br /&gt;
===Startup-Code===&lt;br /&gt;
Em::Blocks fügt standardmäßig einen Startup-Code mit in das Projekt ein. Die wichtigsten Dinge die darin erledigt werden sind folgende:&lt;br /&gt;
&lt;br /&gt;
*Stack und Heap wird angelgt&lt;br /&gt;
*Die Vector-Table wird angelegt&lt;br /&gt;
*Ein Default Reset-Handler wird implementiert, dieser erledigt folgende aufgaben:&lt;br /&gt;
**Kopieren der definierten Daten aus dem Flash in den SRAM&lt;br /&gt;
**&#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; wird aufgerfen, wenn &#039;&#039;&#039;&#039;&#039;__NO_SYSTEM_INIT&#039;&#039;&#039;&#039;&#039; nicht definiert ist&lt;br /&gt;
**Sprung in die &#039;&#039;&#039;&#039;&#039;main()&#039;&#039;&#039;&#039;&#039; Funktion&lt;br /&gt;
*Allen anderen Interrupt-Handler wird eine Default-Funktion &#039;&#039;&#039;&#039;&#039;def_irq_handler&#039;&#039;&#039;&#039;&#039; mit einer &#039;&#039;&#039;&#039;&#039;while(1)&#039;&#039;&#039;&#039;&#039;-Schleife zugewiesen, falls kein anderer Interrupt-Handler existiert.&lt;br /&gt;
&lt;br /&gt;
Normalerweise muss am Startup-Code nichts verändert werden.&lt;br /&gt;
&lt;br /&gt;
===Linker-Script===&lt;br /&gt;
Em::Blocks stellt zwei fertige Linker-Scripts bereit, eins für die Ausführung des Programmes aus dem Flash (&#039;&#039;&#039;&#039;&#039;*_flash.ld&#039;&#039;&#039;&#039;&#039;), das andere für die Ausführung aus dem SRAM (&#039;&#039;&#039;&#039;&#039;*_sram.ld&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Normalerweise muss auch hier nichts geändert werden, es sei den Daten sollen in bestimmten Adressbereichen abgelegt werden (z.B. im Core-Coupled RAM), was ich später noch zum Tutorial hinzufüge.&lt;br /&gt;
&lt;br /&gt;
===Der Takt===&lt;br /&gt;
Jeder Controller oder Prozessor braucht einen Takt, indem er die einzelnen Maschinen-Befehle abarbeiten kann.&lt;br /&gt;
Bei den STM32 Mikrocontrollern kann dieser Takt aus verschiedenen Quellen kommen:&lt;br /&gt;
&lt;br /&gt;
1. High Speed Internal Oszillator (HSI)&lt;br /&gt;
&lt;br /&gt;
2. High Speed External Oszillator (HSE)&lt;br /&gt;
&lt;br /&gt;
3. Low Speed Internal Oszillator (LSI)&lt;br /&gt;
&lt;br /&gt;
4. Low Speed External Oszillator (LSE)&lt;br /&gt;
&lt;br /&gt;
5. Phase-Locked Loop (PLL) (generiert den Takt aus den ersten vier Taktquellen durch Teiler und Faktoren)&lt;br /&gt;
&lt;br /&gt;
Nach einem Reset wird der Controller aus der HSI Taktquelle versorgt (16MHz beim STM32F407VG). Um die voll Performance des Controllers zu erreichen muss die PLL verwendet werden, welche den Takt durch geschickte Teiler und Faktoren vervielfältigt, sodass am Ende der Controller mit der maximalen Taktfrequenz läuft. Die notwendige Initialisierung der PLL findet in der Funktion &#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; statt. Die PLL erzeugt zunächst einen Basistakt:&lt;br /&gt;
&lt;br /&gt;
PLL_VCO = (F_HSE / PLL_M) * PLL_N&lt;br /&gt;
&lt;br /&gt;
Aus diesem Takt wird dann der Takt für den Controller-Kern abgeleitet:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = PLL_VCO / PLL_P&lt;br /&gt;
&lt;br /&gt;
Und der Takt für SDIO / USB / RNG (48MHz):&lt;br /&gt;
&lt;br /&gt;
48MHz = PLL_VCO / PLL_Q&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Durch weiter Teiler werden, die Takte für die einzelnen Busse erzeugt, da diese nicht alle beliebig schnell betrieben werden dürfen.&lt;br /&gt;
&lt;br /&gt;
Genaue Angaben findet man zu dem jeweiligen Clock-System des Controllers im Reference Manual.&lt;br /&gt;
&lt;br /&gt;
Ein Blick in den &amp;quot;Kommentar-Header&amp;quot; verrät, dass von einem externen (HSE) Oszillator von 25MHz ausgegangen wird, der die PLL versorgen soll.&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((25MHz / PLL_M(25)) * PLL_N(336)) / PLL_P(2) = 168MHz&lt;br /&gt;
&lt;br /&gt;
Allerdings stimmt diese Rechnung natürlich nur, wenn wirklich ein 25MHz Quarz am Controller angeschlossen ist. Auf dem STM32F4-Discovery Board befindet sich aber nur ein 8MHz Quarz. Demnach gilt:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((8MHz / PLL_M(25)) * PLL_N(336)) / PLL_P(2) = 53.76MHz&lt;br /&gt;
&lt;br /&gt;
Der Controller läuft also nur mit 53.76MHz, wenn wie ober beschrieben ein Projekt erstellt wird. Allerdings kann dieses Problem durch ändern von den betroffen Defines behoben werden:&lt;br /&gt;
 &lt;br /&gt;
*Dazu geht man in die &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; Datei und passt zur Vollständigkeit erstmal die zum Controller passende Tabelle im &amp;quot;Kommentar-Header&amp;quot; an (Z.57f):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      HSE Frequency(Hz)                      | 8000000&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      PLL_M                                  | 8&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Danach passt man den PPL_M Define (Z.254) an:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/************************* PLL Parameters *************************************/&lt;br /&gt;
/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */&lt;br /&gt;
#define PLL_M      8&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Außerdem muss man den HSE_VALUE Define in der &#039;&#039;&#039;&#039;&#039;inc/stm32f4xx.h&#039;&#039;&#039;&#039;&#039; angepasst werden (Z.122):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#if !defined  (HSE_VALUE)&lt;br /&gt;
  #define HSE_VALUE    ((uint32_t)8000000) /*!&amp;lt; Value of the External oscillator in Hz */&lt;br /&gt;
&lt;br /&gt;
#endif /* HSE_VALUE */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine neue Berechnung zeigt:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((8MHz / PLL_M(8)) * PLL_N(336)) / PLL_P(2) = 168MHz&lt;br /&gt;
&lt;br /&gt;
Jetzt läuft der Controller mit maximaler Geschwindigkeit.&lt;br /&gt;
&lt;br /&gt;
Die Theorie wird durch folgendes Programm verifiziert. Der geviertelte System-Takt SYSCLK wir am Pin PC9 ausgegeben. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);&lt;br /&gt;
&lt;br /&gt;
    GPIO_InitTypeDef GPIOC_InitStructure;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Mode = GPIO_Mode_AF;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_OType = GPIO_OType_PP;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Pin = GPIO_Pin_9;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;&lt;br /&gt;
    GPIO_Init(GPIOC, &amp;amp;GPIOC_InitStructure);&lt;br /&gt;
&lt;br /&gt;
    RCC_MCO2Config(RCC_MCO2Source_SYSCLK, RCC_MCO2Div_4);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Die FPU===&lt;br /&gt;
====Allgemeines====&lt;br /&gt;
STM32F3 und STM32F4 Controller haben eine FPU.&lt;br /&gt;
Damit die FPU richtig verwendet wird, müssen normalerweise zwei Bedingungen erfüllt sein:&lt;br /&gt;
&lt;br /&gt;
1. Der Controller muss die FPU Hardware-seitig aktivieren&lt;br /&gt;
&lt;br /&gt;
2. Damit die FPU auch was zu tuen bekommt, müssen vom Compiler FPU-Instructions erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
Die Em::Blocks IDE verwendet standardmäßig die FPU, wenn eine Vorhanden ist. Hier wird die FPU Hardware-seitig aktiviert (&#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; Z.341):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* FPU settings ------------------------------------------------------------*/&lt;br /&gt;
  #if (__FPU_PRESENT == 1) &amp;amp;&amp;amp; (__FPU_USED == 1)&lt;br /&gt;
    SCB-&amp;gt;CPACR |= ((3UL &amp;lt;&amp;lt; 10*2)|(3UL &amp;lt;&amp;lt; 11*2));  /* set CP10 and CP11 Full Access */&lt;br /&gt;
  #endif&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
__FPU_PRESENT wird in der &#039;&#039;&#039;&#039;&#039;stm32f4xx.h&#039;&#039;&#039;&#039;&#039; definiert.&lt;br /&gt;
__FPU_USED wird von der IDE übernommen (siehe Build-Log): &#039;&#039;&#039;&#039;&#039;-D__FPU_USED&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Außerdem wird der Compiler von der IDE standardmäßig mit dem Argument &#039;&#039;&#039;&#039;&#039;-mfloat-abi=hard&#039;&#039;&#039;&#039;&#039; aufgerufen, wodurch FPU-Instructions erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
====FPU abschalten====&lt;br /&gt;
Um die FPU ab zu schalten (Mir würde jetzt nur Strom sparen als Grund einfallen) geht man wie folgt vor:&lt;br /&gt;
&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; Device -&amp;gt; Policy&#039;&#039;&#039;&#039;&#039; wählt man &#039;&#039;&#039;&#039;&#039;Use target settings&#039;&#039;&#039;&#039;&#039; und über nimmt die Einstellungen, die vorher dort eingetragen waren, allerdings lässt man das Feld &#039;&#039;&#039;&#039;&#039;FP-hardware&#039;&#039;&#039;&#039;&#039; frei.&lt;br /&gt;
&lt;br /&gt;
[[Datei:fpu_1.png|FPU Abschalten Schritt 1]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;Compiler Settings -&amp;gt; Policy&#039;&#039;&#039;&#039;&#039; wählt man dann &#039;&#039;&#039;&#039;&#039;Use target options only&#039;&#039;&#039;&#039;&#039;. Dann kann man unter &#039;&#039;&#039;&#039;&#039;Categories&#039;&#039;&#039;&#039;&#039; die Option &#039;&#039;&#039;&#039;&#039;ARM FPU architecture&#039;&#039;&#039;&#039;&#039; auswählen. Dort stehen dann drei Möglichkeiten für die FPU zur Verfügung:&lt;br /&gt;
&lt;br /&gt;
1. Software-FPU-Library für Gleitkomma-Berechnung verwenden - Keine FPU-Instructions werden generiert (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=soft&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
2. Eine Mischung aus Software- und Hardware-FPU wird verwendet (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=softfp&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
3. Hardware-FPU wird für Gleitkomma-Berechnungen verwendet (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=hard&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
[[Datei:fpu_2.png|FPU Abschalten Schritt 2]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Um die FPU ab zu schalten wählt man natürlich die erste Möglichkeit.&lt;br /&gt;
Bei der 2. und 3. Möglichkeit fügt die IDE auch den Define &#039;&#039;&#039;&#039;&#039;__FPU_USED&#039;&#039;&#039;&#039;&#039; hinzu. Bei Der ersten Möglichkeit nicht. Der Code muss also nicht verändert / auskommentiert werden.&lt;br /&gt;
&lt;br /&gt;
Um die FPU wieder zu aktivieren müssen alle Schritte wieder rückgängig gemacht werden.&lt;br /&gt;
&lt;br /&gt;
Am besten ist es einfach mal alle Möglichkeiten im Einzelschritt durch zu probieren. Dann stellt man schnell fest, ob die FPU aktiviert wir oder nicht. Ein Blick in den erweiterten &#039;&#039;&#039;&#039;&#039;Build-Log&#039;&#039;&#039;&#039;&#039; gibt auch schnell Aufschluss darüber, wie der Compiler aufgerufen wird (siehe Kapitel [http://www.mikrocontroller.net/articles/STM32_-_Einstieg_mit_Em::Blocks#Compilieren Compilieren]).&lt;br /&gt;
&lt;br /&gt;
====Test Programm für die FPU====&lt;br /&gt;
Hier ein kleines Testprogramm, dass misst wie viele Taktzyklen für eine Gleitkomma-Multiplikation gebraucht werden. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define CORE_SysTickEn()    (*((u32*)0xE0001000)) = 0x40000001&lt;br /&gt;
#define CORE_SysTickDis()   (*((u32*)0xE0001000)) = 0x40000000&lt;br /&gt;
#define CORE_GetSysTick()   (*((u32*)0xE0001004))&lt;br /&gt;
&lt;br /&gt;
uint32_t t1, t2, dt;&lt;br /&gt;
float x, y, z;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    x = 53.64f;&lt;br /&gt;
    y = 0.27f;&lt;br /&gt;
&lt;br /&gt;
    CORE_SysTickEn();&lt;br /&gt;
    t1 = CORE_GetSysTick();&lt;br /&gt;
&lt;br /&gt;
    z = x * y;&lt;br /&gt;
&lt;br /&gt;
    t2 = CORE_GetSysTick();&lt;br /&gt;
    CORE_SysTickDis();&lt;br /&gt;
&lt;br /&gt;
    dt = (t2 - t1) - 9; //9 Takt-Zyklen werden für die Messung gebraucht &lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Booten aus dem SRAM==&lt;br /&gt;
STM32 Controller haben die Möglichkeit Code aus dem Flash als auch aus dem SRAM auszuführen. Um eine Anwenung per Debugger in des SRAM zu laden sind nur wenige Schritte erforderlich:&lt;br /&gt;
&lt;br /&gt;
*Um das Linkerscript für den SRAM zu verwenden geht man zu: &#039;&#039;&#039;&#039;&#039;Build options... -&amp;gt; Device&#039;&#039;&#039;&#039;&#039; dort wählt man unter &#039;&#039;&#039;&#039;&#039;Policy&#039;&#039;&#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;Use target settings&#039;&#039;&#039;&#039;&#039; aus und übernimmt die vorherigen Einstellungen, nur unter &#039;&#039;&#039;&#039;&#039;Linker script*&#039;&#039;&#039;&#039;&#039; gibt man &#039;&#039;&#039;&#039;&#039;.\stm32f407vg_sram.ld&#039;&#039;&#039;&#039;&#039; an&lt;br /&gt;
&lt;br /&gt;
*Dann muss man noch unter &#039;&#039;&#039;&#039;&#039;Debug -&amp;gt; Interfaces -&amp;gt; Settings&#039;&#039;&#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;Vector table start&#039;&#039;&#039;&#039;&#039; auf 0x20000000 ändern und &#039;&#039;&#039;&#039;&#039;Execute from RAM&#039;&#039;&#039;&#039;&#039; auswählen.&lt;br /&gt;
&lt;br /&gt;
Anschließend kann man die Anwendung ganz normal debuggen. Nach einem Reset muss die Anwenung erneut mit dem Debugger gestartet werden.&lt;br /&gt;
&lt;br /&gt;
=Fortsetzung folgt..=&lt;br /&gt;
Kritik, Wünsche usw. sind gerne erwünscht, am besten hier in den Thread posten: [http://www.mikrocontroller.net/topic/323750 Neues STM32 Tutorial]&lt;br /&gt;
&lt;br /&gt;
[[Category:ARM]]&lt;br /&gt;
[[Category:STM32]]&lt;/div&gt;</summary>
		<author><name>Avrprogger</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=STM32_-_Einstieg_mit_Em::Blocks&amp;diff=81563</id>
		<title>STM32 - Einstieg mit Em::Blocks</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=STM32_-_Einstieg_mit_Em::Blocks&amp;diff=81563"/>
		<updated>2014-02-13T10:50:26Z</updated>

		<summary type="html">&lt;p&gt;Avrprogger: jkl&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In diesem Tutorial werde ich versuchen, möglichst einfach, die ersten Schritte zur Entwicklung von STM32 Anwenungen mit der Em::Blocks IDE zu erklären. Hier soll nicht so stark auf die einzelnen Peripherie-Module der Controller eingegangen werden, sondern mehr auf die IDE und die verschieden Libraries, wie die CMSIS Library, die DSP-Library, die Standard-Peripheral-Library, die USB-Library und vllt. über Ethernet. Ich denke ein Kapitel zu FreeRTOS wird es auch geben. Auserdem steht im Vordergrund Sachen wie z.B. booten aus dem SRAM, In-Application-Programming, FPU, Core-Coupled-RAM usw. Mal sehn wie weit ich komme ;)&lt;br /&gt;
&lt;br /&gt;
==Die Entwicklungsumgebung==&lt;br /&gt;
===Hardware===&lt;br /&gt;
Zum testen der Anwendungen, benutze ich das STM32F4-Discovery Board, welches einen Debugger, Peripherie und natürlich einen STM32 Controller (STM32F407VGT6) enthält. Deshalb sind alle Beispiele hier für den STM32F407VG Controller ausgelegt, können aber meisten 1:1 auf andere Controller portiert werden. Ich werde auch möglichsts keine STM32F4-Discovery Board spezifischen Libraries verwenden, damit der Portierungs-Vorgang möglichsts einfach bleibt.&lt;br /&gt;
&lt;br /&gt;
===Software===&lt;br /&gt;
In diesem Tutorial verwende ich [http://www.emblocks.org/ Em::Blocks] als IDE. Em::Blocks ist eine kostenlose, uneingeschränkte IDE, die alle STM32 Mikrcontroller unterstützt und sehr einfach zu bedienen ist.&lt;br /&gt;
nach dem Download kann die IDE per Dialog, sehr einfach, installiert werden. Als Compiler beinhaltet Em::Blocks den &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
Die IDE unterstützt zurzeit den ST-Link, den J-Link und es gibt eine Generic-Vorlage, durch welche andere Debugger konfiguriert werden können.&lt;br /&gt;
&lt;br /&gt;
Außerdem muss noch der passende Treiber für den Debugger installiert werden. Verwendet man ein Discovery-Board muss der [http://www.st.com/web/catalog/tools/FM146/CL1984/SC724/SS1677/PF251168 ST-Link/V2]-Treiber heruntergeladen und installiert werden. (Die Installation muss evtl. als Administrator ausgeführt werden, da sonst die Installation unvollständig wird.) Nach der Installation des Treibers kann man den Debugger über die entsprechende USB Schnittstelle an den PC anschließen und es sollte die Meldung von Windows kommen, dass der richtige Treiber gefunden wurde.&lt;br /&gt;
&lt;br /&gt;
===Libraries===&lt;br /&gt;
Zum programmieren benötigt man noch die [http://www.arm.com/products/processors/cortex-m/cortex-microcontroller-software-interface-standard.php CMSIS] und die Standard-Peripheral-Library (z.B. für die F4 Controller [http://www.st.com/stonline/stappl/productcatalog/app?page=partNumberSearchPage&amp;amp;levelid=SS1577&amp;amp;parentid=1743&amp;amp;resourcetype=SW Standard-Peripheral-Library-F4]), die man am besten in einen Ordner (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\STM32&#039;&#039;&#039;&#039;&#039;) entpackt&lt;br /&gt;
&lt;br /&gt;
==Basis-Wissen zur IDE==&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von Dateien zum Projekt===&lt;br /&gt;
Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf &amp;lt;ProjektName&amp;gt; -&amp;gt; Add files...&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Enfernen von Dateien aus dem Projekt===&lt;br /&gt;
Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf die Datei / mehrere Dateien auswählen -&amp;gt; Remove file from project&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
Die Dateien werden lediglich aus dem Projekt entfernt und nicht von der Festplatte gelöscht.&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von Include-Pfaden===&lt;br /&gt;
Sofern die Include-Datei(en) nicht im standard Include-Ordner &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; des Projektes liegen, muss man den Pfad zum Projekt hinzufügen, damit der Compiler die Include-Dateien später auch finden kann. Man geht wie folgt vor: Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; Search Directories -&amp;gt; Add&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von globalen Defines zum Build===&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; #defines&#039;&#039;&#039;&#039;&#039; können globale Defines hinzugefügt werden.&lt;br /&gt;
&lt;br /&gt;
===Compilieren===&lt;br /&gt;
Entweder über das &#039;&#039;&#039;&#039;&#039;Build&#039;&#039;&#039;&#039;&#039; Menü oder über &#039;&#039;&#039;&#039;&#039;F7&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Um eine genau Ausgabe des Compiler-Aufrufes mit allen Argumenten zu bekommen, geht man im &#039;&#039;&#039;&#039;&#039;Settings&#039;&#039;&#039;&#039;&#039; Menü auf &#039;&#039;&#039;&#039;&#039;Tools...&#039;&#039;&#039;&#039;&#039; und dann auf &#039;&#039;&#039;&#039;&#039;Toolchain executables&#039;&#039;&#039;&#039;&#039;. Ganz unten, unter &#039;&#039;&#039;&#039;&#039;Logging&#039;&#039;&#039;&#039;&#039; kann man dann &#039;&#039;&#039;&#039;&#039;Full command line&#039;&#039;&#039;&#039;&#039; auswählen.&lt;br /&gt;
&lt;br /&gt;
====Compiler Optionen====&lt;br /&gt;
=====Optimierung=====&lt;br /&gt;
Standardmäßig verwendet Em::Blocks keine Optimierung. Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; Categories: Optimization&#039;&#039;&#039;&#039;&#039; kann zwischen verschieden Optimierungen ausgewählt werden.&lt;br /&gt;
&lt;br /&gt;
=====Verschiedene C-Standards=====&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; Categories: Language standard&#039;&#039;&#039;&#039;&#039; kann man zwischen verschieden C-Standard auswählen, wie z.B, C99.&lt;br /&gt;
(Mit C99 können auch die Lauf-Variable in der for-Schleife deklariert werden: for(int i;..))&lt;br /&gt;
&lt;br /&gt;
===Debuggen===&lt;br /&gt;
*Als erstes den Debugger starten über das &#039;&#039;&#039;&#039;&#039;Debug&#039;&#039;&#039;&#039;&#039; Menü und &#039;&#039;&#039;&#039;&#039;Start/stop Debug Session&#039;&#039;&#039;&#039;&#039; oder über &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
*Danach läuft die Anwendung auf dem Controller und warten im &#039;&#039;&#039;&#039;&#039;Reset_Handler&#039;&#039;&#039;&#039;&#039; auf Einzelschritt- bzw. Run- Befehle (&#039;&#039;&#039;&#039;&#039;F5, F10, F11&#039;&#039;&#039;&#039;&#039; usw..(siehe &#039;&#039;&#039;&#039;&#039;Debug-Menü&#039;&#039;&#039;&#039;&#039; für alle Möglichkeiten))&lt;br /&gt;
&lt;br /&gt;
*Mit &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039; wird die Debug-Session auch wieder beendet&lt;br /&gt;
&lt;br /&gt;
*Unter &#039;&#039;&#039;&#039;&#039;Debug -&amp;gt; Interfaces -&amp;gt; Target settings&#039;&#039;&#039;&#039;&#039; können Eigenschaften, wie z.B &#039;&#039;&#039;&#039;&#039;Run to main()&#039;&#039;&#039;&#039;&#039; aktiviert werden.&lt;br /&gt;
&lt;br /&gt;
===Projekt als Template abspeichern===&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;File -&amp;gt; Save project as template...&#039;&#039;&#039;&#039;&#039;. Das Template erscheint dann im Projekt-Dialog unter &#039;&#039;&#039;&#039;&#039;User templates&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Das erste Projekt erstellen==&lt;br /&gt;
Hier erkläre ich, wie man am Besten (aus meiner Sicht), ein neues Projekt von Grund auf erstellt, sodass man hinterher, den Controller-Kern über die CMSIS-Library und die Peripherie über die Register steuern kann.&lt;br /&gt;
&lt;br /&gt;
===1. Projekt mit der IDE erstellen===&lt;br /&gt;
Nach der Installation der oben beschriebenen Komponenten erstellt man am besten ein Verzeichnis (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\EmBlocks&#039;&#039;&#039;&#039;&#039;), indem später alle Projekte gespeichert werden. Für Libraries kann man auch noch ein Verzeichnis (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\STM32&#039;&#039;&#039;&#039;&#039;) erstellen, wo alle Libraries gespeichert werden, die man für die Projekt brauchen.&lt;br /&gt;
&lt;br /&gt;
Als nächstes starten man EmBlocks. Bei dem ersten Start öffnet sich ein Fenster, wo verschiedene Compiler angezeigt werden, die Em::Blocks findet. Dort wählt man den &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039; aus und klickt &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039;. Nun sollte sich das Hauptfenster von Em::Blocks öffnen. Über &#039;&#039;&#039;&#039;&#039;Create a new Project&#039;&#039;&#039;&#039;&#039; oder &#039;&#039;&#039;&#039;&#039;File -&amp;gt; New -&amp;gt; Project&#039;&#039;&#039;&#039;&#039; ruft man den Projekt-Dialog auf und kann ein neues Projekt erzeugen.&lt;br /&gt;
&lt;br /&gt;
Auf der Ersten Seite wählen man den &#039;&#039;&#039;&#039;&#039;STmicro-ARM&#039;&#039;&#039;&#039;&#039; Projekt-Typ aus.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_1.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auf der nächsten Seite wird man darauf hingewiesen, dass das der entsprechende Projekt-Typ-Dialog ausgeführt wird. Hier kann man ein Häkchen bei &#039;&#039;&#039;&#039;&#039;Skip this page next time&#039;&#039;&#039;&#039;&#039; setzen und auf &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; klicken.&lt;br /&gt;
&lt;br /&gt;
Im nächsten Schritt wählen man das zuvor erstellt Verzeichnis unter &#039;&#039;&#039;&#039;&#039;Folder to create Project in&#039;&#039;&#039;&#039;&#039; aus, indem später alle Projekt gespeichert werden. Außerdem geben wir dem Projekt einen Namen (z.B. &#039;&#039;&#039;&#039;&#039;FirstProject&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_2.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danach muss man einen Compiler auswählen und bestimmen, welche Projekt-Konfigurationen erszeugt werden sollen. Unter &#039;&#039;&#039;&#039;&#039;Compiler&#039;&#039;&#039;&#039;&#039; wählt man &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039; und man kann das Häkchen bei &#039;&#039;&#039;&#039;&#039;Create &amp;quot;Release&amp;quot; configuration&#039;&#039;&#039;&#039;&#039; entfernen, da diese unnötig ist, die Debug-Konfiguration sollte eig. immer ausreichen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_3.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auf den folgenden Seite wird der Controller ausgewählt. Verwendet man ein STM32F4-Discovery Board müssen folgende Dinge gewählt werden: &#039;&#039;&#039;&#039;&#039;Cortex_M4 (F3xx - F4xx) -&amp;gt; STM32F4xx (Cortex M4 with FPU) -&amp;gt; STM32F407VG&#039;&#039;&#039;&#039;&#039;. Leider sind die Auswahl Möglichkeiten nicht ganz richtig, da auch die F3 Controller einen Cortex M4 Kern und eine FPU haben (Ist aber nicht so wichtig, ist nur eine formale Sache). Außerdem entfernt man das Häkchen bei &#039;&#039;&#039;&#039;&#039;Standard Peripherals Library&#039;&#039;&#039;&#039;&#039; (Wie man die Standard-Peripheral-Library einbindet und verwendet erkläre ich später). Man kann auch das Häkchen bei &#039;&#039;&#039;&#039;&#039;Create hex file for Realease target&#039;&#039;&#039;&#039;&#039; entfernen.&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;Stack Size&#039;&#039;&#039;&#039;&#039; und &#039;&#039;&#039;&#039;&#039;Heap Size&#039;&#039;&#039;&#039;&#039; wird die Größe von Stack und Heap festgelegt. Für eine erste Anwendung kann man die Einstellungen so lassen (Stack-Size: 0x0100 =&amp;gt; 256 Byte Stack und Heap-Size: 0x0000 =&amp;gt; kein Heap). Mit &#039;&#039;&#039;&#039;&#039;Finish&#039;&#039;&#039;&#039;&#039; ist der Projekt Dialog abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_4.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danach sollten sich zwei neue Fenster öffnen, um die Debug-Eigenschaften fest zu legen.&lt;br /&gt;
Verwendet man ein Discovery Board/ST-Link müssen die Einstellungen wie auf dem Bild gewählt werden. Über den Button &#039;&#039;&#039;&#039;&#039;Settings&#039;&#039;&#039;&#039;&#039; öffnet sich das zweite Fenster, falls sich dieses nicht schon von alleine öffnen sollte. Nach den Schließen der Fenster über &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; ist der Projekt Dialog beendet und ein neues Projekt steht zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_5_1.png|Debug Eigenschaften 1. Fenster]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_5_2.png|Debug Eigenschaften 2. Fenster]]&lt;br /&gt;
&lt;br /&gt;
===2. CMSIS-Library und Startup-Code hinzufügen===&lt;br /&gt;
Wenn man sich, nachdem man ein neues Projekt in der IDE erstellt hat, die bereits vorhandenen Dateien im Projekt ansieht, stellt man fest, das bereits ein Ordner &#039;&#039;&#039;&#039;&#039;cmsis&#039;&#039;&#039;&#039;&#039; existiert, der einige wichtige Include-Dateien der CMSIS-Library enthält. Allerdings sind das wirklich nur die wichtigsten Include-Dateien der CMSIS-Library und dazu noch, die aus einer älternen Version. Ich ziehe es deshalb vor die &amp;quot;Mini-CMSIS-Libraray&amp;quot; und die &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c/.h&#039;&#039;&#039;&#039;&#039; Dateien des Projektes durch aktuellere Versionen zu ersetzen. So ist später auch die Integration  von anderen Libraries, wie z.B. der CMSIS-DSP-Libarary einfacher.  &lt;br /&gt;
&lt;br /&gt;
Zunächst gehen man in das Projekt-Verzeichnis und löscht:&lt;br /&gt;
*Den Ordner &#039;&#039;&#039;&#039;&#039;cmsis&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Alle Dateien im Include Verzeichnis &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; im &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner&lt;br /&gt;
&lt;br /&gt;
Außerdem entfernt man auch alle gelöschten Dateien in der IDE aus dem Projekt mit &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Rechts Klick -&amp;gt; Remove file from project&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Es sollte folgende Verzeichnis Struktur überbleiben:&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_6.png|Überbleibende Dateien]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Jetzt müssen die gelöschten Dateien durch die aktuelleren ersetzt werden.&lt;br /&gt;
&lt;br /&gt;
*Dazu kopieren man den gesamten Ordner &#039;&#039;&#039;&#039;&#039;CMSIS&#039;&#039;&#039;&#039;&#039; aus dem CMSIS Download in das Projekt Verzeichnis.&lt;br /&gt;
&lt;br /&gt;
*Aus dem Standard-Peripheral-Library Download kopiert man von &#039;&#039;&#039;&#039;&#039;Libraries\CMSIS\Device\ST\STM32F4xx\Include&#039;&#039;&#039;&#039;&#039; alle Dateien in den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projekt Verzeichnisses&lt;br /&gt;
&lt;br /&gt;
*Aus der Standard-Peripheral-Library kopieren man ebenfalls von &#039;&#039;&#039;&#039;&#039;Libraries\CMSIS\Device\ST\STM32F4xx\Source\Templates&#039;&#039;&#039;&#039;&#039; die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; in den &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner des Projekts&lt;br /&gt;
&lt;br /&gt;
Anschließend müssen die neuen Dateien in der IDE dem Projekt hinzugefügt werden. Dazu benutzt man &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Rechts Klick -&amp;gt; Add files&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
*Aus dem &#039;&#039;&#039;&#039;&#039;CMSIS&#039;&#039;&#039;&#039;&#039; Ordner im Projekt Verzeichnis werden aus den Unterorder &#039;&#039;&#039;&#039;&#039;Include&#039;&#039;&#039;&#039;&#039; folgende Dateien dem Projekt hinzugefügt:&lt;br /&gt;
**arm_common_tables.h&lt;br /&gt;
**arm_const_structs.h&lt;br /&gt;
**arm_math.h&lt;br /&gt;
**core_cm4.h&lt;br /&gt;
**core_cm4_simd.h&lt;br /&gt;
**core_cmFunc.h&lt;br /&gt;
**core_cmInstr.h&lt;br /&gt;
*Alle Dateien aus den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projektes&lt;br /&gt;
*Die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; aus dem &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner&lt;br /&gt;
&lt;br /&gt;
So sollte die Struktur dann aussehen:&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_7.png|Anwenungs-Grundgerüst]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Da einige Dateien der Libraries später bearbeitet werden müssen und Schreibgeschützt sind, weise ich hier schonmal darauf hin, das der Schreibschutz in der IDE über &#039;&#039;&#039;&#039;&#039;Rechts Klick auf die Datei -&amp;gt; Properties -&amp;gt; Häkchen bei &amp;quot;File is read only&amp;quot; entfernen&#039;&#039;&#039;&#039;&#039; entfert werden kann.&lt;br /&gt;
&lt;br /&gt;
Damit die IDE die Header-Dateien der CMSIS Library auch finden kann, weil diese ja nicht im standard Include Ordner &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; liegen, muss unter &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Build Options -&amp;gt; Search Directories&#039;&#039;&#039;&#039;&#039; der Pfad &#039;&#039;&#039;&#039;&#039;CMSIS\Include&#039;&#039;&#039;&#039;&#039; hinzugefügt werden.&lt;br /&gt;
&lt;br /&gt;
Compiliert man jetzt das Projekt mit &#039;&#039;&#039;&#039;&#039;F7&#039;&#039;&#039;&#039;&#039; gibt es ein paar Fehler Meldungen, weil keine Controller-Reihe ausgewählt wurde. Ebenfalls unter &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Build Options -&amp;gt; Compiler Settings -&amp;gt; #defines&#039;&#039;&#039;&#039;&#039; wird der Define &#039;&#039;&#039;&#039;&#039;STM32F40_41xxx&#039;&#039;&#039;&#039;&#039; hinzugefügt.&lt;br /&gt;
&lt;br /&gt;
Beim erneuten Compilieren sollten sich nun keine neuen Fehler ergeben.&lt;br /&gt;
&lt;br /&gt;
===3. Das erste Programm===&lt;br /&gt;
Nachdem ein grundsätzliches &amp;quot;Gerüst&amp;quot; fertig ist, kann man den ersten Code schreiben.&lt;br /&gt;
main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC-&amp;gt;AHB1ENR |= RCC_AHB1ENR_GPIODEN;    //Takt für GPIO aktivieren&lt;br /&gt;
    GPIOD-&amp;gt;MODER |= GPIO_MODER_MODER15_0;   //GPIOD Pin15 als Ausgang&lt;br /&gt;
    GPIOD-&amp;gt;BSRRL |= GPIO_BSRR_BS_15;        //GPIOD Pin15 auf High ziehen&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039; wird dann der Debugger gestartet. Hat der Debugger das Projekt erfolgreich übertragen kann die Ausführung mit &#039;&#039;&#039;&#039;&#039;F5&#039;&#039;&#039;&#039;&#039; begonnen werden.&lt;br /&gt;
&lt;br /&gt;
==Libraries einbinden/verwenden==&lt;br /&gt;
===Einbinden der Standard-Peripheral-Library===&lt;br /&gt;
Um nicht immer die einzelnen Register, wie im ersten &amp;quot;bare-metal&amp;quot; Beispiel, aus dem Reference-Manual zu suchen und zu beschreiben, gibt es von ST die Standard Peripheral Library, die diese Aufgaben übernimmt und mit der sich die &amp;quot;normale/grundlegende&amp;quot; (Alles außer USB und Ethernet) Peripherie recht einfach steuern lässt. Ich kopiere die Standard-Peripheral-Library immer per Hand in das Projekt. Darduch hat man auch gleich die aktuellste Version (in den älteren Version gibt es einige Bugs). Um die Library zu verwenden erzeugt man wie oben beschrieben ein neues Grundgerüst (den Haken bei &#039;&#039;&#039;&#039;&#039;Use Standard Peripherals Library&#039;&#039;&#039;&#039;&#039; also auch wieder weg nehmen) und kopiert als erstes den Ordner &#039;&#039;&#039;&#039;&#039;Libraries\STM32F4xx_StdPeriph_Driver&#039;&#039;&#039;&#039;&#039; aus dem Standard-Peripheral-Library Download in das Projekt-Verzeichnis. Außerdem muss man die Datei &#039;&#039;&#039;&#039;&#039;Project\STM32F4xx_StdPeriph_Templates\stm32f4xx_conf.h&#039;&#039;&#039;&#039;&#039; ebenfalls aus dem Standard-Peripheral-Library Download in den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projektes kopieren. In der IDE fügt man den Include-Path &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\inc&#039;&#039;&#039;&#039;&#039; ein, wie bereits bei der CMSIS-Library (s.o.) beschrieben.&lt;br /&gt;
Außerdem muss noch &#039;&#039;&#039;&#039;&#039;USE_STDPERIPH_DRIVER&#039;&#039;&#039;&#039;&#039; als Define in der IDE hinzugefügt werden (s.o.).&lt;br /&gt;
Danach fügt man die Source- und Include-Dateien aus dem Ordner &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\inc&#039;&#039;&#039;&#039;&#039; und &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\src&#039;&#039;&#039;&#039;&#039; dem Project mit &#039;&#039;&#039;&#039;&#039;&amp;lt;Project Name&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Add files&#039;&#039;&#039;&#039;&#039; hinzu, allerdings nur die, für welche auch der Controller die entsprechende Peripherie besitzt. Beim STM32F4-Discovery Board / STM32F407VG Controller dürfen also nicht folgende Dateien nicht mit hinzugefügt werden, weil diese Peripherie nur bei anderen Controller vorhanden ist:&lt;br /&gt;
&lt;br /&gt;
*stm32f4xx_dma2d.c/.h&lt;br /&gt;
*stm32f4xx_fmc.c/.h&lt;br /&gt;
*stm32f4xx_ltdc.c/.h&lt;br /&gt;
*stm32f4xx_sai.c/.h&lt;br /&gt;
&lt;br /&gt;
Daraus resultiert folgende Struktur:&lt;br /&gt;
&lt;br /&gt;
[[Datei:stdperiphlib_2.png|Header-Struktur]] [[Datei:stdperiphlib_1.png|Source-Struktur]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Anschließen kann die Standard-Peripheral-Library benutz werden.&lt;br /&gt;
main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);&lt;br /&gt;
&lt;br /&gt;
    GPIO_InitTypeDef GPIOD_InitStructure;&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Mode = GPIO_Mode_OUT;     //Als Ausgang&lt;br /&gt;
    GPIOD_InitStructure.GPIO_OType = GPIO_OType_PP;    //Push-Pull Betrieb&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Pin = GPIO_Pin_15;        //Pin 15 (STM32F4-Discovery: Blaue LED)&lt;br /&gt;
    GPIOD_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;  //Kein Pull-Up oder Pull-Down Widerstand aktiviert&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Speed = GPIO_Speed_25MHz; //25MHz Update-Rate&lt;br /&gt;
    GPIO_Init(GPIOD, &amp;amp;GPIOD_InitStructure);&lt;br /&gt;
&lt;br /&gt;
    GPIO_SetBits(GPIOD, GPIO_Pin_15);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Einbinden der DSP-Library===&lt;br /&gt;
STM32F3 / STM32F4 Microcontroller haben neben der FPU noch einen Digital-Signal-Processor (DSP). Die DSP dient hauptsächlich dazu, viele Daten schnell zu verarbeiten (z.B. Video- oder Audiosignal). Der CMSIS-Download beinhaltet dazu neben der eigentlichen CMSIS-Library auch noch eine DSP-Library. Diese Library stellt sowohl einfache, mathematische Funktionen wie addieren, multiplizieren usw. als auch komplexe Funktionen, wie z.B  einen IIR-Filter, zur Verfügung. Die DSP-Library ist weiter aufgeteilt in kleinere Module, wie z.B. BasicMathFunctions, FilteringFunctions usw. (siehe &#039;&#039;&#039;&#039;&#039;CMSIS\DSP-Library\Source&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
Um die DSP-Library zu verwenden müssen nur die Source-Files des benötigten Moduls einbinden.&lt;br /&gt;
(&#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Add files...&#039;&#039;&#039;&#039;&#039;). Außerdem muss in der &#039;&#039;&#039;&#039;&#039;main.c&#039;&#039;&#039;&#039;&#039; der Include &#039;&#039;&#039;&#039;&#039;arm_math.h&#039;&#039;&#039;&#039;&#039; eingebunden werden. Aus irgendeinem Grund gibt es dann jedoch die Warnung: &amp;quot;Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)&amp;quot;. Ich hab noch nicht rausgefunden, wieso diese Warnung auftaucht. Die Warnung verschwindet, wenn man in der &#039;&#039;&#039;&#039;&#039;Build options...&#039;&#039;&#039;&#039;&#039; das Define &#039;&#039;&#039;&#039;&#039;__FPU_PRESENT&#039;&#039;&#039;&#039;&#039; hinzufügt (Ich weiß selber das das keine schöne Lösung ist, eine andere hab ich jedoch noch nicht gefunden). Jetzt kann die DSP-Library verwedet werden. Das Beispiel multipliziert zwei Buffer miteinander. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
#include &amp;quot;arm_math.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    float32_t x[1024];&lt;br /&gt;
    float32_t y[1024];&lt;br /&gt;
    float32_t z[1024];&lt;br /&gt;
&lt;br /&gt;
    for(uint16_t i = 0; i &amp;lt; 1024; i++)&lt;br /&gt;
    {&lt;br /&gt;
        x[i] = i;&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for(uint16_t i = 0; i &amp;lt; 1024; i++)&lt;br /&gt;
    {&lt;br /&gt;
        y[i] = PI;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    arm_mult_f32(x, y, z, 1024);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Startup-Code, Linker-Script, Takt, FPU usw.==&lt;br /&gt;
===Startup-Code===&lt;br /&gt;
Em::Blocks fügt standardmäßig einen Startup-Code mit in das Projekt ein. Die wichtigsten Dinge die darin erledigt werden sind folgende:&lt;br /&gt;
&lt;br /&gt;
*Stack und Heap wird angelgt&lt;br /&gt;
*Die Vector-Table wird angelegt&lt;br /&gt;
*Ein Default Reset-Handler wird implementiert, dieser erledigt folgende aufgaben:&lt;br /&gt;
**Kopieren der definierten Daten aus dem Flash in den SRAM&lt;br /&gt;
**&#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; wird aufgerfen, wenn &#039;&#039;&#039;&#039;&#039;__NO_SYSTEM_INIT&#039;&#039;&#039;&#039;&#039; nicht definiert ist&lt;br /&gt;
**Sprung in die &#039;&#039;&#039;&#039;&#039;main()&#039;&#039;&#039;&#039;&#039; Funktion&lt;br /&gt;
*Allen anderen Interrupt-Handler wird eine Default-Funktion &#039;&#039;&#039;&#039;&#039;def_irq_handler&#039;&#039;&#039;&#039;&#039; mit einer &#039;&#039;&#039;&#039;&#039;while(1)&#039;&#039;&#039;&#039;&#039;-Schleife zugewiesen, falls kein anderer Interrupt-Handler existiert.&lt;br /&gt;
&lt;br /&gt;
Normalerweise muss am Startup-Code nichts verändert werden.&lt;br /&gt;
&lt;br /&gt;
===Linker-Script===&lt;br /&gt;
Em::Blocks stellt zwei fertige Linker-Scripts bereit, eins für die Ausführung des Programmes aus dem Flash (&#039;&#039;&#039;&#039;&#039;*_flash.ld&#039;&#039;&#039;&#039;&#039;), das andere für die Ausführung aus dem SRAM (&#039;&#039;&#039;&#039;&#039;*_sram.ld&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Normalerweise muss auch hier nichts geändert werden, es sei den Daten sollen in bestimmten Adressbereichen abgelegt werden (z.B. im Core-Coupled RAM), was ich später noch zum Tutorial hinzufüge.&lt;br /&gt;
&lt;br /&gt;
===Der Takt===&lt;br /&gt;
Jeder Controller oder Prozessor braucht einen Takt, indem er die einzelnen Maschinen-Befehle abarbeiten kann.&lt;br /&gt;
Bei den STM32 Mikrocontrollern kann dieser Takt aus verschiedenen Quellen kommen:&lt;br /&gt;
&lt;br /&gt;
1. High Speed Internal Oszillator (HSI)&lt;br /&gt;
&lt;br /&gt;
2. High Speed External Oszillator (HSE)&lt;br /&gt;
&lt;br /&gt;
3. Low Speed Internal Oszillator (LSI)&lt;br /&gt;
&lt;br /&gt;
4. Low Speed External Oszillator (LSE)&lt;br /&gt;
&lt;br /&gt;
5. Phase-Locked Loop (PLL) (generiert den Takt aus den ersten vier Taktquellen durch Teiler und Faktoren)&lt;br /&gt;
&lt;br /&gt;
Nach einem Reset wird der Controller aus der HSI Taktquelle versorgt (16MHz beim STM32F407VG). Um die voll Performance des Controllers zu erreichen muss die PLL verwendet werden, welche den Takt durch geschickte Teiler und Faktoren vervielfältigt, sodass am Ende der Controller mit der maximalen Taktfrequenz läuft. Die notwendige Initialisierung der PLL findet in der Funktion &#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; statt. Die PLL erzeugt zunächst einen Basistakt:&lt;br /&gt;
&lt;br /&gt;
PLL_VCO = (F_HSE / PLL_M) * PLL_N&lt;br /&gt;
&lt;br /&gt;
Aus diesem Takt wird dann der Takt für den Controller-Kern abgeleitet:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = PLL_VCO / PLL_P&lt;br /&gt;
&lt;br /&gt;
Und der Takt für SDIO / USB / RNG (48MHz):&lt;br /&gt;
&lt;br /&gt;
48MHz = PLL_VCO / PLL_Q&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Durch weiter Teiler werden, die Takte für die einzelnen Busse erzeugt, da diese nicht alle beliebig schnell betrieben werden dürfen.&lt;br /&gt;
&lt;br /&gt;
Genaue Angaben findet man zu dem jeweiligen Clock-System des Controllers im Reference Manual.&lt;br /&gt;
&lt;br /&gt;
Ein Blick in den &amp;quot;Kommentar-Header&amp;quot; verrät, dass von einem externen (HSE) Oszillator von 25MHz ausgegangen wird, der die PLL versorgen soll.&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((25MHz / PLL_M(25)) * PLL_N(336)) / PLL_P(2) = 168MHz&lt;br /&gt;
&lt;br /&gt;
Allerdings stimmt diese Rechnung natürlich nur, wenn wirklich ein 25MHz Quarz am Controller angeschlossen ist. Auf dem STM32F4-Discovery Board befindet sich aber nur ein 8MHz Quarz. Demnach gilt:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((8MHz / PLL_M(25)) * PLL_N(336)) / PLL_P(2) = 53.76MHz&lt;br /&gt;
&lt;br /&gt;
Der Controller läuft also nur mit 53.76MHz, wenn wie ober beschrieben ein Projekt erstellt wird. Allerdings kann dieses Problem durch ändern von den betroffen Defines behoben werden:&lt;br /&gt;
 &lt;br /&gt;
*Dazu geht man in die &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; Datei und passt zur Vollständigkeit erstmal die zum Controller passende Tabelle im &amp;quot;Kommentar-Header&amp;quot; an (Z.57f):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      HSE Frequency(Hz)                      | 8000000&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      PLL_M                                  | 8&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Danach passt man den PPL_M Define (Z.254) an:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/************************* PLL Parameters *************************************/&lt;br /&gt;
/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */&lt;br /&gt;
#define PLL_M      8&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Außerdem muss man den HSE_VALUE Define in der &#039;&#039;&#039;&#039;&#039;inc/stm32f4xx.h&#039;&#039;&#039;&#039;&#039; angepasst werden (Z.122):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#if !defined  (HSE_VALUE)&lt;br /&gt;
  #define HSE_VALUE    ((uint32_t)8000000) /*!&amp;lt; Value of the External oscillator in Hz */&lt;br /&gt;
&lt;br /&gt;
#endif /* HSE_VALUE */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine neue Berechnung zeigt:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((8MHz / PLL_M(8)) * PLL_N(336)) / PLL_P(2) = 168MHz&lt;br /&gt;
&lt;br /&gt;
Jetzt läuft der Controller mit maximaler Geschwindigkeit.&lt;br /&gt;
&lt;br /&gt;
Die Theorie wird durch folgendes Programm verifiziert. Der geviertelte System-Takt SYSCLK wir am Pin PC9 ausgegeben. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);&lt;br /&gt;
&lt;br /&gt;
    GPIO_InitTypeDef GPIOC_InitStructure;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Mode = GPIO_Mode_AF;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_OType = GPIO_OType_PP;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Pin = GPIO_Pin_9;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;&lt;br /&gt;
    GPIO_Init(GPIOC, &amp;amp;GPIOC_InitStructure);&lt;br /&gt;
&lt;br /&gt;
    RCC_MCO2Config(RCC_MCO2Source_SYSCLK, RCC_MCO2Div_4);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Die FPU===&lt;br /&gt;
====Allgemeines====&lt;br /&gt;
STM32F3 und STM32F4 Controller haben eine FPU.&lt;br /&gt;
Damit die FPU richtig verwendet wird, müssen normalerweise zwei Bedingungen erfüllt sein:&lt;br /&gt;
&lt;br /&gt;
1. Der Controller muss die FPU Hardware-seitig aktivieren&lt;br /&gt;
&lt;br /&gt;
2. Damit die FPU auch was zu tuen bekommt, müssen vom Compiler FPU-Instructions erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
Die Em::Blocks IDE verwendet standardmäßig die FPU, wenn eine Vorhanden ist. Hier wird die FPU Hardware-seitig aktiviert (&#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; Z.341):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* FPU settings ------------------------------------------------------------*/&lt;br /&gt;
  #if (__FPU_PRESENT == 1) &amp;amp;&amp;amp; (__FPU_USED == 1)&lt;br /&gt;
    SCB-&amp;gt;CPACR |= ((3UL &amp;lt;&amp;lt; 10*2)|(3UL &amp;lt;&amp;lt; 11*2));  /* set CP10 and CP11 Full Access */&lt;br /&gt;
  #endif&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
__FPU_PRESENT wird in der &#039;&#039;&#039;&#039;&#039;stm32f4xx.h&#039;&#039;&#039;&#039;&#039; definiert.&lt;br /&gt;
__FPU_USED wird von der IDE übernommen (siehe Build-Log): &#039;&#039;&#039;&#039;&#039;-D__FPU_USED&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Außerdem wird der Compiler von der IDE standardmäßig mit dem Argument &#039;&#039;&#039;&#039;&#039;-mfloat-abi=hard&#039;&#039;&#039;&#039;&#039; aufgerufen, wodurch FPU-Instructions erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
====FPU abschalten====&lt;br /&gt;
Um die FPU ab zu schalten (Mir würde jetzt nur Strom sparen als Grund einfallen) geht man wie folgt vor:&lt;br /&gt;
&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; Device -&amp;gt; Policy&#039;&#039;&#039;&#039;&#039; wählt man &#039;&#039;&#039;&#039;&#039;Use target settings&#039;&#039;&#039;&#039;&#039; und über nimmt die Einstellungen, die vorher dort eingetragen waren, allerdings lässt man das Feld &#039;&#039;&#039;&#039;&#039;FP-hardware&#039;&#039;&#039;&#039;&#039; frei.&lt;br /&gt;
&lt;br /&gt;
[[Datei:fpu_1.png|FPU Abschalten Schritt 1]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;Compiler Settings -&amp;gt; Policy&#039;&#039;&#039;&#039;&#039; wählt man dann &#039;&#039;&#039;&#039;&#039;Use target options only&#039;&#039;&#039;&#039;&#039;. Dann kann man unter &#039;&#039;&#039;&#039;&#039;Categories&#039;&#039;&#039;&#039;&#039; die Option &#039;&#039;&#039;&#039;&#039;ARM FPU architecture&#039;&#039;&#039;&#039;&#039; auswählen. Dort stehen dann drei Möglichkeiten für die FPU zur Verfügung:&lt;br /&gt;
&lt;br /&gt;
1. Software-FPU-Library für Gleitkomma-Berechnung verwenden - Keine FPU-Instructions werden generiert (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=soft&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
2. Eine Mischung aus Software- und Hardware-FPU wird verwendet (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=softfp&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
3. Hardware-FPU wird für Gleitkomma-Berechnungen verwendet (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=hard&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
[[Datei:fpu_2.png|FPU Abschalten Schritt 2]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Um die FPU ab zu schalten wählt man natürlich die erste Möglichkeit.&lt;br /&gt;
Bei der 2. und 3. Möglichkeit fügt die IDE auch den Define &#039;&#039;&#039;&#039;&#039;__FPU_USED&#039;&#039;&#039;&#039;&#039; hinzu. Bei Der ersten Möglichkeit nicht. Der Code muss also nicht verändert / auskommentiert werden.&lt;br /&gt;
&lt;br /&gt;
Um die FPU wieder zu aktivieren müssen alle Schritte wieder rückgängig gemacht werden.&lt;br /&gt;
&lt;br /&gt;
Am besten ist es einfach mal alle Möglichkeiten im Einzelschritt durch zu probieren. Dann stellt man schnell fest, ob die FPU aktiviert wir oder nicht. Ein Blick in den erweiterten &#039;&#039;&#039;&#039;&#039;Build-Log&#039;&#039;&#039;&#039;&#039; gibt auch schnell Aufschluss darüber, wie der Compiler aufgerufen wird (siehe Kapitel [http://www.mikrocontroller.net/articles/STM32_-_Einstieg_mit_Em::Blocks#Compilieren Compilieren]).&lt;br /&gt;
&lt;br /&gt;
====Test Programm für die FPU====&lt;br /&gt;
Hier ein kleines Testprogramm, dass misst wie viele Taktzyklen für eine Gleitkomma-Multiplikation gebraucht werden. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define CORE_SysTickEn()    (*((u32*)0xE0001000)) = 0x40000001&lt;br /&gt;
#define CORE_SysTickDis()   (*((u32*)0xE0001000)) = 0x40000000&lt;br /&gt;
#define CORE_GetSysTick()   (*((u32*)0xE0001004))&lt;br /&gt;
&lt;br /&gt;
uint32_t t1, t2, dt;&lt;br /&gt;
float x, y, z;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    x = 53.64f;&lt;br /&gt;
    y = 0.27f;&lt;br /&gt;
&lt;br /&gt;
    CORE_SysTickEn();&lt;br /&gt;
    t1 = CORE_GetSysTick();&lt;br /&gt;
&lt;br /&gt;
    z = x * y;&lt;br /&gt;
&lt;br /&gt;
    t2 = CORE_GetSysTick();&lt;br /&gt;
    CORE_SysTickDis();&lt;br /&gt;
&lt;br /&gt;
    dt = (t2 - t1) - 9; //9 Takt-Zyklen werden für die Messung gebraucht &lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Booten aus dem SRAM==&lt;br /&gt;
STM32 Controller haben die Möglichkeit Code aus dem Flash als auch aus dem SRAM auszuführen. Um eine Anwenung per Debugger in des SRAM zu laden sind nur wenige Schritte erforderlich:&lt;br /&gt;
&lt;br /&gt;
*Um das Linkerscript für den SRAM zu verwenden geht man zu: &#039;&#039;&#039;&#039;&#039;Build options... -&amp;gt; Device&#039;&#039;&#039;&#039;&#039; dort wählt man unter &#039;&#039;&#039;&#039;&#039;Policy&#039;&#039;&#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;Use target settings&#039;&#039;&#039;&#039;&#039; aus und übernimmt die vorherigen Einstellungen, nur unter &#039;&#039;&#039;&#039;&#039;Linker script*&#039;&#039;&#039;&#039;&#039; gibt man &#039;&#039;&#039;&#039;&#039;.\stm32f407vg_sram.ld&#039;&#039;&#039;&#039;&#039; an&lt;br /&gt;
&lt;br /&gt;
*Dann muss man noch unter &#039;&#039;&#039;&#039;&#039;Debug -&amp;gt; Interfaces -&amp;gt; Settings&#039;&#039;&#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;Vector table start&#039;&#039;&#039;&#039;&#039; auf 0x20000000 ändern und &#039;&#039;&#039;&#039;&#039;Execute from RAM&#039;&#039;&#039;&#039;&#039; auswählen.&lt;br /&gt;
&lt;br /&gt;
Anschließend kann man die Anwendung ganz normal debuggen. Nach einem Reset muss die Anwenung erneut mit dem Debugger gestartet werden.&lt;br /&gt;
&lt;br /&gt;
=Fortsetzung folgt..=&lt;br /&gt;
Kritik, Wünsche usw. sind gerne erwünscht, am besten hier in den Thread posten: [http://www.mikrocontroller.net/topic/323750 Neues STM32 Tutorial]&lt;br /&gt;
&lt;br /&gt;
[[Category:ARM]]&lt;br /&gt;
[[Category:STM32]]&lt;/div&gt;</summary>
		<author><name>Avrprogger</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=STM32_-_Einstieg_mit_Em::Blocks&amp;diff=81562</id>
		<title>STM32 - Einstieg mit Em::Blocks</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=STM32_-_Einstieg_mit_Em::Blocks&amp;diff=81562"/>
		<updated>2014-02-13T10:50:01Z</updated>

		<summary type="html">&lt;p&gt;Avrprogger: fgh&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In diesem Tutorial werde ich versuchen, möglichst einfach, die ersten Schritte zur Entwicklung von STM32 Anwenungen mit der Em::Blocks IDE zu erklären. Hier soll nicht so stark auf die einzelnen Peripherie-Module der Controller eingegangen werden, sondern mehr auf die IDE und die verschieden Libraries, wie die CMSIS Library, die DSP-Library, die Standard-Peripheral-Library, die USB-Library und vllt. über Ethernet. Ich denke ein Kapitel zu FreeRTOS wird es auch geben. Auserdem steht im Vordergrund Sachen wie z.B. booten aus dem SRAM, In-Application-Programming, FPU, Core-Coupled-RAM usw. Mal sehn wie weit ich komme ;)&lt;br /&gt;
&lt;br /&gt;
==Die Entwicklungsumgebung==&lt;br /&gt;
===Hardware===&lt;br /&gt;
Zum testen der Anwendungen, benutze ich das STM32F4-Discovery Board, welches einen Debugger, Peripherie und natürlich einen STM32 Controller (STM32F407VGT6) enthält. Deshalb sind alle Beispiele hier für den STM32F407VG Controller ausgelegt, können aber meisten 1:1 auf andere Controller portiert werden. Ich werde auch möglichsts keine STM32F4-Discovery Board spezifischen Libraries verwenden, damit der Portierungs-Vorgang möglichsts einfach bleibt.&lt;br /&gt;
&lt;br /&gt;
===Software===&lt;br /&gt;
In diesem Tutorial verwende ich [http://www.emblocks.org/ Em::Blocks] als IDE. Em::Blocks ist eine kostenlose, uneingeschränkte IDE, die alle STM32 Mikrcontroller unterstützt und sehr einfach zu bedienen ist.&lt;br /&gt;
nach dem Download kann die IDE per Dialog, sehr einfach, installiert werden. Als Compiler beinhaltet Em::Blocks den &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
Die IDE unterstützt zurzeit den ST-Link, den J-Link und es gibt eine Generic-Vorlage, durch welche andere Debugger konfiguriert werden können.&lt;br /&gt;
&lt;br /&gt;
Außerdem muss noch der passende Treiber für den Debugger installiert werden. Verwendet man ein Discovery-Board muss der [http://www.st.com/web/catalog/tools/FM146/CL1984/SC724/SS1677/PF251168 ST-Link/V2]-Treiber heruntergeladen und installiert werden. (Die Installation muss evtl. als Administrator ausgeführt werden, da sonst die Installation unvollständig wird.) Nach der Installation des Treibers kann man den Debugger über die entsprechende USB Schnittstelle an den PC anschließen und es sollte die Meldung von Windows kommen, dass der richtige Treiber gefunden wurde.&lt;br /&gt;
&lt;br /&gt;
===Libraries===&lt;br /&gt;
Zum programmieren benötigt man noch die [http://www.arm.com/products/processors/cortex-m/cortex-microcontroller-software-interface-standard.php CMSIS] und die Standard-Peripheral-Library (z.B. für die F4 Controller [http://www.st.com/stonline/stappl/productcatalog/app?page=partNumberSearchPage&amp;amp;levelid=SS1577&amp;amp;parentid=1743&amp;amp;resourcetype=SW Standard-Peripheral-Library-F4]), die man am besten in einen Ordner (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\STM32&#039;&#039;&#039;&#039;&#039;) entpackt&lt;br /&gt;
&lt;br /&gt;
==Basis-Wissen zur IDE==&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von Dateien zum Projekt===&lt;br /&gt;
Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf &amp;lt;ProjektName&amp;gt; -&amp;gt; Add files...&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Enfernen von Dateien aus dem Projekt===&lt;br /&gt;
Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf die Datei / mehrere Dateien auswählen -&amp;gt; Remove file from project&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
Die Dateien werden lediglich aus dem Projekt entfernt und nicht von der Festplatte gelöscht.&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von Include-Pfaden===&lt;br /&gt;
Sofern die Include-Datei(en) nicht im standard Include-Ordner &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; des Projektes liegen, muss man den Pfad zum Projekt hinzufügen, damit der Compiler die Include-Dateien später auch finden kann. Man geht wie folgt vor: Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; Search Directories -&amp;gt; Add&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von globalen Defines zum Build===&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; #defines&#039;&#039;&#039;&#039;&#039; können globale Defines hinzugefügt werden.&lt;br /&gt;
&lt;br /&gt;
===Compilieren===&lt;br /&gt;
Entweder über das &#039;&#039;&#039;&#039;&#039;Build&#039;&#039;&#039;&#039;&#039; Menü oder über &#039;&#039;&#039;&#039;&#039;F7&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Um eine genau Ausgabe des Compiler-Aufrufes mit allen Argumenten zu bekommen, geht man im &#039;&#039;&#039;&#039;&#039;Settings&#039;&#039;&#039;&#039;&#039; Menü auf &#039;&#039;&#039;&#039;&#039;Tools...&#039;&#039;&#039;&#039;&#039; und dann auf &#039;&#039;&#039;&#039;&#039;Toolchain executables&#039;&#039;&#039;&#039;&#039;. Ganz unten, unter &#039;&#039;&#039;&#039;&#039;Logging&#039;&#039;&#039;&#039;&#039; kann man dann &#039;&#039;&#039;&#039;&#039;Full command line&#039;&#039;&#039;&#039;&#039; auswählen.&lt;br /&gt;
&lt;br /&gt;
====Compiler Optionen====&lt;br /&gt;
=====Optimierung=====&lt;br /&gt;
Standardmäßig verwendet Em::Blocks keine Optimierung. Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; Categories: Optimization&#039;&#039;&#039;&#039;&#039; kann zwischen verschieden Optimierungen ausgewählt werden.&lt;br /&gt;
&lt;br /&gt;
=====Verschiedene C-Standards=====&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; Categories: Language standard&#039;&#039;&#039;&#039;&#039; kann man zwischen verschieden C-Standard auswählen, wie z.B, C99.&lt;br /&gt;
(Mit C99 können auch die Lauf-Variable in der for-Schleife deklariert werden: for(int i;..))&lt;br /&gt;
&lt;br /&gt;
===Debuggen===&lt;br /&gt;
*Als erstes den Debugger starten über das &#039;&#039;&#039;&#039;&#039;Debug&#039;&#039;&#039;&#039;&#039; Menü und &#039;&#039;&#039;&#039;&#039;Start/stop Debug Session&#039;&#039;&#039;&#039;&#039; oder über &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
*Danach läuft die Anwendung auf dem Controller und warten im &#039;&#039;&#039;&#039;&#039;Reset_Handler&#039;&#039;&#039;&#039;&#039; auf Einzelschritt- bzw. Run- Befehle (&#039;&#039;&#039;&#039;&#039;F5, F10, F11&#039;&#039;&#039;&#039;&#039; usw..(siehe &#039;&#039;&#039;&#039;&#039;Debug-Menü&#039;&#039;&#039;&#039;&#039; für alle Möglichkeiten))&lt;br /&gt;
&lt;br /&gt;
*Mit &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039; wird die Debug-Session auch wieder beendet&lt;br /&gt;
&lt;br /&gt;
*Unter &#039;&#039;&#039;&#039;&#039;Debug -&amp;gt; Interfaces -&amp;gt; Target settings&#039;&#039;&#039;&#039;&#039; können Eigenschaften, wie z.B &#039;&#039;&#039;&#039;&#039;Run to main()&#039;&#039;&#039;&#039;&#039; aktiviert werden.&lt;br /&gt;
&lt;br /&gt;
===Projekt als Template abspeichern===&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;File -&amp;gt; Save project as template...&#039;&#039;&#039;&#039;&#039;. Das Template erscheint dann im Projekt-Dialog unter &#039;&#039;&#039;&#039;&#039;User templates&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Das erste Projekt erstellen==&lt;br /&gt;
Hier erkläre ich, wie man am Besten (aus meiner Sicht), ein neues Projekt von Grund auf erstellt, sodass man hinterher, den Controller-Kern über die CMSIS-Library und die Peripherie über die Register steuern kann.&lt;br /&gt;
&lt;br /&gt;
===1. Projekt mit der IDE erstellen===&lt;br /&gt;
Nach der Installation der oben beschriebenen Komponenten erstellt man am besten ein Verzeichnis (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\EmBlocks&#039;&#039;&#039;&#039;&#039;), indem später alle Projekte gespeichert werden. Für Libraries kann man auch noch ein Verzeichnis (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\STM32&#039;&#039;&#039;&#039;&#039;) erstellen, wo alle Libraries gespeichert werden, die man für die Projekt brauchen.&lt;br /&gt;
&lt;br /&gt;
Als nächstes starten man EmBlocks. Bei dem ersten Start öffnet sich ein Fenster, wo verschiedene Compiler angezeigt werden, die Em::Blocks findet. Dort wählt man den &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039; aus und klickt &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039;. Nun sollte sich das Hauptfenster von Em::Blocks öffnen. Über &#039;&#039;&#039;&#039;&#039;Create a new Project&#039;&#039;&#039;&#039;&#039; oder &#039;&#039;&#039;&#039;&#039;File -&amp;gt; New -&amp;gt; Project&#039;&#039;&#039;&#039;&#039; ruft man den Projekt-Dialog auf und kann ein neues Projekt erzeugen.&lt;br /&gt;
&lt;br /&gt;
Auf der Ersten Seite wählen man den &#039;&#039;&#039;&#039;&#039;STmicro-ARM&#039;&#039;&#039;&#039;&#039; Projekt-Typ aus.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_1.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auf der nächsten Seite wird man darauf hingewiesen, dass das der entsprechende Projekt-Typ-Dialog ausgeführt wird. Hier kann man ein Häkchen bei &#039;&#039;&#039;&#039;&#039;Skip this page next time&#039;&#039;&#039;&#039;&#039; setzen und auf &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; klicken.&lt;br /&gt;
&lt;br /&gt;
Im nächsten Schritt wählen man das zuvor erstellt Verzeichnis unter &#039;&#039;&#039;&#039;&#039;Folder to create Project in&#039;&#039;&#039;&#039;&#039; aus, indem später alle Projekt gespeichert werden. Außerdem geben wir dem Projekt einen Namen (z.B. &#039;&#039;&#039;&#039;&#039;FirstProject&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_2.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danach muss man einen Compiler auswählen und bestimmen, welche Projekt-Konfigurationen erszeugt werden sollen. Unter &#039;&#039;&#039;&#039;&#039;Compiler&#039;&#039;&#039;&#039;&#039; wählt man &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039; und man kann das Häkchen bei &#039;&#039;&#039;&#039;&#039;Create &amp;quot;Release&amp;quot; configuration&#039;&#039;&#039;&#039;&#039; entfernen, da diese unnötig ist, die Debug-Konfiguration sollte eig. immer ausreichen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_3.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auf den folgenden Seite wird der Controller ausgewählt. Verwendet man ein STM32F4-Discovery Board müssen folgende Dinge gewählt werden: &#039;&#039;&#039;&#039;&#039;Cortex_M4 (F3xx - F4xx) -&amp;gt; STM32F4xx (Cortex M4 with FPU) -&amp;gt; STM32F407VG&#039;&#039;&#039;&#039;&#039;. Leider sind die Auswahl Möglichkeiten nicht ganz richtig, da auch die F3 Controller einen Cortex M4 Kern und eine FPU haben (Ist aber nicht so wichtig, ist nur eine formale Sache). Außerdem entfernt man das Häkchen bei &#039;&#039;&#039;&#039;&#039;Standard Peripherals Library&#039;&#039;&#039;&#039;&#039; (Wie man die Standard-Peripheral-Library einbindet und verwendet erkläre ich später). Man kann auch das Häkchen bei &#039;&#039;&#039;&#039;&#039;Create hex file for Realease target&#039;&#039;&#039;&#039;&#039; entfernen.&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;Stack Size&#039;&#039;&#039;&#039;&#039; und &#039;&#039;&#039;&#039;&#039;Heap Size&#039;&#039;&#039;&#039;&#039; wird die Größe von Stack und Heap festgelegt. Für eine erste Anwendung kann man die Einstellungen so lassen (Stack-Size: 0x0100 =&amp;gt; 256 Byte Stack und Heap-Size: 0x0000 =&amp;gt; kein Heap). Mit &#039;&#039;&#039;&#039;&#039;Finish&#039;&#039;&#039;&#039;&#039; ist der Projekt Dialog abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_4.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danach sollten sich zwei neue Fenster öffnen, um die Debug-Eigenschaften fest zu legen.&lt;br /&gt;
Verwendet man ein Discovery Board/ST-Link müssen die Einstellungen wie auf dem Bild gewählt werden. Über den Button &#039;&#039;&#039;&#039;&#039;Settings&#039;&#039;&#039;&#039;&#039; öffnet sich das zweite Fenster, falls sich dieses nicht schon von alleine öffnen sollte. Nach den Schließen der Fenster über &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; ist der Projekt Dialog beendet und ein neues Projekt steht zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_5_1.png|Debug Eigenschaften 1. Fenster]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_5_2.png|Debug Eigenschaften 2. Fenster]]&lt;br /&gt;
&lt;br /&gt;
===2. CMSIS-Library und Startup-Code hinzufügen===&lt;br /&gt;
Wenn man sich, nachdem man ein neues Projekt in der IDE erstellt hat, die bereits vorhandenen Dateien im Projekt ansieht, stellt man fest, das bereits ein Ordner &#039;&#039;&#039;&#039;&#039;cmsis&#039;&#039;&#039;&#039;&#039; existiert, der einige wichtige Include-Dateien der CMSIS-Library enthält. Allerdings sind das wirklich nur die wichtigsten Include-Dateien der CMSIS-Library und dazu noch, die aus einer älternen Version. Ich ziehe es deshalb vor die &amp;quot;Mini-CMSIS-Libraray&amp;quot; und die &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c/.h&#039;&#039;&#039;&#039;&#039; Dateien des Projektes durch aktuellere Versionen zu ersetzen. So ist später auch die Integration  von anderen Libraries, wie z.B. der CMSIS-DSP-Libarary einfacher.  &lt;br /&gt;
&lt;br /&gt;
Zunächst gehen man in das Projekt-Verzeichnis und löscht:&lt;br /&gt;
*Den Ordner &#039;&#039;&#039;&#039;&#039;cmsis&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Alle Dateien im Include Verzeichnis &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; im &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner&lt;br /&gt;
&lt;br /&gt;
Außerdem entfernt man auch alle gelöschten Dateien in der IDE aus dem Projekt mit &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Rechts Klick -&amp;gt; Remove file from project&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Es sollte folgende Verzeichnis Struktur überbleiben:&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_6.png|Überbleibende Dateien]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Jetzt müssen die gelöschten Dateien durch die aktuelleren ersetzt werden.&lt;br /&gt;
&lt;br /&gt;
*Dazu kopieren man den gesamten Ordner &#039;&#039;&#039;&#039;&#039;CMSIS&#039;&#039;&#039;&#039;&#039; aus dem CMSIS Download in das Projekt Verzeichnis.&lt;br /&gt;
&lt;br /&gt;
*Aus dem Standard-Peripheral-Library Download kopiert man von &#039;&#039;&#039;&#039;&#039;Libraries\CMSIS\Device\ST\STM32F4xx\Include&#039;&#039;&#039;&#039;&#039; alle Dateien in den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projekt Verzeichnisses&lt;br /&gt;
&lt;br /&gt;
*Aus der Standard-Peripheral-Library kopieren man ebenfalls von &#039;&#039;&#039;&#039;&#039;Libraries\CMSIS\Device\ST\STM32F4xx\Source\Templates&#039;&#039;&#039;&#039;&#039; die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; in den &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner des Projekts&lt;br /&gt;
&lt;br /&gt;
Anschließend müssen die neuen Dateien in der IDE dem Projekt hinzugefügt werden. Dazu benutzt man &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Rechts Klick -&amp;gt; Add files&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
*Aus dem &#039;&#039;&#039;&#039;&#039;CMSIS&#039;&#039;&#039;&#039;&#039; Ordner im Projekt Verzeichnis werden aus den Unterorder &#039;&#039;&#039;&#039;&#039;Include&#039;&#039;&#039;&#039;&#039; folgende Dateien dem Projekt hinzugefügt:&lt;br /&gt;
**arm_common_tables.h&lt;br /&gt;
**arm_const_structs.h&lt;br /&gt;
**arm_math.h&lt;br /&gt;
**core_cm4.h&lt;br /&gt;
**core_cm4_simd.h&lt;br /&gt;
**core_cmFunc.h&lt;br /&gt;
**core_cmInstr.h&lt;br /&gt;
*Alle Dateien aus den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projektes&lt;br /&gt;
*Die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; aus dem &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner&lt;br /&gt;
&lt;br /&gt;
So sollte die Struktur dann aussehen:&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_7.png|Anwenungs-Grundgerüst]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Da einige Dateien der Libraries später bearbeitet werden müssen und Schreibgeschützt sind, weise ich hier schonmal darauf hin, das der Schreibschutz in der IDE über &#039;&#039;&#039;&#039;&#039;Rechts Klick auf die Datei -&amp;gt; Properties -&amp;gt; Häkchen bei &amp;quot;File is read only&amp;quot; entfernen&#039;&#039;&#039;&#039;&#039; entfert werden kann.&lt;br /&gt;
&lt;br /&gt;
Damit die IDE die Header-Dateien der CMSIS Library auch finden kann, weil diese ja nicht im standard Include Ordner &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; liegen, muss unter &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Build Options -&amp;gt; Search Directories&#039;&#039;&#039;&#039;&#039; der Pfad &#039;&#039;&#039;&#039;&#039;CMSIS\Include&#039;&#039;&#039;&#039;&#039; hinzugefügt werden.&lt;br /&gt;
&lt;br /&gt;
Compiliert man jetzt das Projekt mit &#039;&#039;&#039;&#039;&#039;F7&#039;&#039;&#039;&#039;&#039; gibt es ein paar Fehler Meldungen, weil keine Controller-Reihe ausgewählt wurde. Ebenfalls unter &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Build Options -&amp;gt; Compiler Settings -&amp;gt; #defines&#039;&#039;&#039;&#039;&#039; wird der Define &#039;&#039;&#039;&#039;&#039;STM32F40_41xxx&#039;&#039;&#039;&#039;&#039; hinzugefügt.&lt;br /&gt;
&lt;br /&gt;
Beim erneuten Compilieren sollten sich nun keine neuen Fehler ergeben.&lt;br /&gt;
&lt;br /&gt;
===3. Das erste Programm===&lt;br /&gt;
Nachdem ein grundsätzliches &amp;quot;Gerüst&amp;quot; fertig ist, kann man den ersten Code schreiben.&lt;br /&gt;
main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC-&amp;gt;AHB1ENR |= RCC_AHB1ENR_GPIODEN;    //Takt für GPIO aktivieren&lt;br /&gt;
    GPIOD-&amp;gt;MODER |= GPIO_MODER_MODER15_0;   //GPIOD Pin15 als Ausgang&lt;br /&gt;
    GPIOD-&amp;gt;BSRRL |= GPIO_BSRR_BS_15;        //GPIOD Pin15 auf High ziehen&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039; wird dann der Debugger gestartet. Hat der Debugger das Projekt erfolgreich übertragen kann die Ausführung mit &#039;&#039;&#039;&#039;&#039;F5&#039;&#039;&#039;&#039;&#039; begonnen werden.&lt;br /&gt;
&lt;br /&gt;
==Libraries einbinden/verwenden==&lt;br /&gt;
===Einbinden der Standard-Peripheral-Library===&lt;br /&gt;
Um nicht immer die einzelnen Register, wie im ersten &amp;quot;bare-metal&amp;quot; Beispiel, aus dem Reference-Manual zu suchen und zu beschreiben, gibt es von ST die Standard Peripheral Library, die diese Aufgaben übernimmt und mit der sich die &amp;quot;normale/grundlegende&amp;quot; (Alles außer USB und Ethernet) Peripherie recht einfach steuern lässt. Ich kopiere die Standard-Peripheral-Library immer per Hand in das Projekt. Darduch hat man auch gleich die aktuellste Version (in den älteren Version gibt es einige Bugs). Um die Library zu verwenden erzeugt man wie oben beschrieben ein neues Grundgerüst (den Haken bei &#039;&#039;&#039;&#039;&#039;Use Standard Peripherals Library&#039;&#039;&#039;&#039;&#039; also auch wieder weg nehmen&#039;&#039;&#039;&#039;&#039;) und kopiert als erstes den Ordner &#039;&#039;&#039;&#039;&#039;Libraries\STM32F4xx_StdPeriph_Driver&#039;&#039;&#039;&#039;&#039; aus dem Standard-Peripheral-Library Download in das Projekt-Verzeichnis. Außerdem muss man die Datei &#039;&#039;&#039;&#039;&#039;Project\STM32F4xx_StdPeriph_Templates\stm32f4xx_conf.h&#039;&#039;&#039;&#039;&#039; ebenfalls aus dem Standard-Peripheral-Library Download in den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projektes kopieren. In der IDE fügt man den Include-Path &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\inc&#039;&#039;&#039;&#039;&#039; ein, wie bereits bei der CMSIS-Library (s.o.) beschrieben.&lt;br /&gt;
Außerdem muss noch &#039;&#039;&#039;&#039;&#039;USE_STDPERIPH_DRIVER&#039;&#039;&#039;&#039;&#039; als Define in der IDE hinzugefügt werden (s.o.).&lt;br /&gt;
Danach fügt man die Source- und Include-Dateien aus dem Ordner &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\inc&#039;&#039;&#039;&#039;&#039; und &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\src&#039;&#039;&#039;&#039;&#039; dem Project mit &#039;&#039;&#039;&#039;&#039;&amp;lt;Project Name&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Add files&#039;&#039;&#039;&#039;&#039; hinzu, allerdings nur die, für welche auch der Controller die entsprechende Peripherie besitzt. Beim STM32F4-Discovery Board / STM32F407VG Controller dürfen also nicht folgende Dateien nicht mit hinzugefügt werden, weil diese Peripherie nur bei anderen Controller vorhanden ist:&lt;br /&gt;
&lt;br /&gt;
*stm32f4xx_dma2d.c/.h&lt;br /&gt;
*stm32f4xx_fmc.c/.h&lt;br /&gt;
*stm32f4xx_ltdc.c/.h&lt;br /&gt;
*stm32f4xx_sai.c/.h&lt;br /&gt;
&lt;br /&gt;
Daraus resultiert folgende Struktur:&lt;br /&gt;
&lt;br /&gt;
[[Datei:stdperiphlib_2.png|Header-Struktur]] [[Datei:stdperiphlib_1.png|Source-Struktur]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Anschließen kann die Standard-Peripheral-Library benutz werden.&lt;br /&gt;
main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);&lt;br /&gt;
&lt;br /&gt;
    GPIO_InitTypeDef GPIOD_InitStructure;&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Mode = GPIO_Mode_OUT;     //Als Ausgang&lt;br /&gt;
    GPIOD_InitStructure.GPIO_OType = GPIO_OType_PP;    //Push-Pull Betrieb&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Pin = GPIO_Pin_15;        //Pin 15 (STM32F4-Discovery: Blaue LED)&lt;br /&gt;
    GPIOD_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;  //Kein Pull-Up oder Pull-Down Widerstand aktiviert&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Speed = GPIO_Speed_25MHz; //25MHz Update-Rate&lt;br /&gt;
    GPIO_Init(GPIOD, &amp;amp;GPIOD_InitStructure);&lt;br /&gt;
&lt;br /&gt;
    GPIO_SetBits(GPIOD, GPIO_Pin_15);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Einbinden der DSP-Library===&lt;br /&gt;
STM32F3 / STM32F4 Microcontroller haben neben der FPU noch einen Digital-Signal-Processor (DSP). Die DSP dient hauptsächlich dazu, viele Daten schnell zu verarbeiten (z.B. Video- oder Audiosignal). Der CMSIS-Download beinhaltet dazu neben der eigentlichen CMSIS-Library auch noch eine DSP-Library. Diese Library stellt sowohl einfache, mathematische Funktionen wie addieren, multiplizieren usw. als auch komplexe Funktionen, wie z.B  einen IIR-Filter, zur Verfügung. Die DSP-Library ist weiter aufgeteilt in kleinere Module, wie z.B. BasicMathFunctions, FilteringFunctions usw. (siehe &#039;&#039;&#039;&#039;&#039;CMSIS\DSP-Library\Source&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
Um die DSP-Library zu verwenden müssen nur die Source-Files des benötigten Moduls einbinden.&lt;br /&gt;
(&#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Add files...&#039;&#039;&#039;&#039;&#039;). Außerdem muss in der &#039;&#039;&#039;&#039;&#039;main.c&#039;&#039;&#039;&#039;&#039; der Include &#039;&#039;&#039;&#039;&#039;arm_math.h&#039;&#039;&#039;&#039;&#039; eingebunden werden. Aus irgendeinem Grund gibt es dann jedoch die Warnung: &amp;quot;Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)&amp;quot;. Ich hab noch nicht rausgefunden, wieso diese Warnung auftaucht. Die Warnung verschwindet, wenn man in der &#039;&#039;&#039;&#039;&#039;Build options...&#039;&#039;&#039;&#039;&#039; das Define &#039;&#039;&#039;&#039;&#039;__FPU_PRESENT&#039;&#039;&#039;&#039;&#039; hinzufügt (Ich weiß selber das das keine schöne Lösung ist, eine andere hab ich jedoch noch nicht gefunden). Jetzt kann die DSP-Library verwedet werden. Das Beispiel multipliziert zwei Buffer miteinander. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
#include &amp;quot;arm_math.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    float32_t x[1024];&lt;br /&gt;
    float32_t y[1024];&lt;br /&gt;
    float32_t z[1024];&lt;br /&gt;
&lt;br /&gt;
    for(uint16_t i = 0; i &amp;lt; 1024; i++)&lt;br /&gt;
    {&lt;br /&gt;
        x[i] = i;&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for(uint16_t i = 0; i &amp;lt; 1024; i++)&lt;br /&gt;
    {&lt;br /&gt;
        y[i] = PI;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    arm_mult_f32(x, y, z, 1024);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Startup-Code, Linker-Script, Takt, FPU usw.==&lt;br /&gt;
===Startup-Code===&lt;br /&gt;
Em::Blocks fügt standardmäßig einen Startup-Code mit in das Projekt ein. Die wichtigsten Dinge die darin erledigt werden sind folgende:&lt;br /&gt;
&lt;br /&gt;
*Stack und Heap wird angelgt&lt;br /&gt;
*Die Vector-Table wird angelegt&lt;br /&gt;
*Ein Default Reset-Handler wird implementiert, dieser erledigt folgende aufgaben:&lt;br /&gt;
**Kopieren der definierten Daten aus dem Flash in den SRAM&lt;br /&gt;
**&#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; wird aufgerfen, wenn &#039;&#039;&#039;&#039;&#039;__NO_SYSTEM_INIT&#039;&#039;&#039;&#039;&#039; nicht definiert ist&lt;br /&gt;
**Sprung in die &#039;&#039;&#039;&#039;&#039;main()&#039;&#039;&#039;&#039;&#039; Funktion&lt;br /&gt;
*Allen anderen Interrupt-Handler wird eine Default-Funktion &#039;&#039;&#039;&#039;&#039;def_irq_handler&#039;&#039;&#039;&#039;&#039; mit einer &#039;&#039;&#039;&#039;&#039;while(1)&#039;&#039;&#039;&#039;&#039;-Schleife zugewiesen, falls kein anderer Interrupt-Handler existiert.&lt;br /&gt;
&lt;br /&gt;
Normalerweise muss am Startup-Code nichts verändert werden.&lt;br /&gt;
&lt;br /&gt;
===Linker-Script===&lt;br /&gt;
Em::Blocks stellt zwei fertige Linker-Scripts bereit, eins für die Ausführung des Programmes aus dem Flash (&#039;&#039;&#039;&#039;&#039;*_flash.ld&#039;&#039;&#039;&#039;&#039;), das andere für die Ausführung aus dem SRAM (&#039;&#039;&#039;&#039;&#039;*_sram.ld&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Normalerweise muss auch hier nichts geändert werden, es sei den Daten sollen in bestimmten Adressbereichen abgelegt werden (z.B. im Core-Coupled RAM), was ich später noch zum Tutorial hinzufüge.&lt;br /&gt;
&lt;br /&gt;
===Der Takt===&lt;br /&gt;
Jeder Controller oder Prozessor braucht einen Takt, indem er die einzelnen Maschinen-Befehle abarbeiten kann.&lt;br /&gt;
Bei den STM32 Mikrocontrollern kann dieser Takt aus verschiedenen Quellen kommen:&lt;br /&gt;
&lt;br /&gt;
1. High Speed Internal Oszillator (HSI)&lt;br /&gt;
&lt;br /&gt;
2. High Speed External Oszillator (HSE)&lt;br /&gt;
&lt;br /&gt;
3. Low Speed Internal Oszillator (LSI)&lt;br /&gt;
&lt;br /&gt;
4. Low Speed External Oszillator (LSE)&lt;br /&gt;
&lt;br /&gt;
5. Phase-Locked Loop (PLL) (generiert den Takt aus den ersten vier Taktquellen durch Teiler und Faktoren)&lt;br /&gt;
&lt;br /&gt;
Nach einem Reset wird der Controller aus der HSI Taktquelle versorgt (16MHz beim STM32F407VG). Um die voll Performance des Controllers zu erreichen muss die PLL verwendet werden, welche den Takt durch geschickte Teiler und Faktoren vervielfältigt, sodass am Ende der Controller mit der maximalen Taktfrequenz läuft. Die notwendige Initialisierung der PLL findet in der Funktion &#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; statt. Die PLL erzeugt zunächst einen Basistakt:&lt;br /&gt;
&lt;br /&gt;
PLL_VCO = (F_HSE / PLL_M) * PLL_N&lt;br /&gt;
&lt;br /&gt;
Aus diesem Takt wird dann der Takt für den Controller-Kern abgeleitet:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = PLL_VCO / PLL_P&lt;br /&gt;
&lt;br /&gt;
Und der Takt für SDIO / USB / RNG (48MHz):&lt;br /&gt;
&lt;br /&gt;
48MHz = PLL_VCO / PLL_Q&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Durch weiter Teiler werden, die Takte für die einzelnen Busse erzeugt, da diese nicht alle beliebig schnell betrieben werden dürfen.&lt;br /&gt;
&lt;br /&gt;
Genaue Angaben findet man zu dem jeweiligen Clock-System des Controllers im Reference Manual.&lt;br /&gt;
&lt;br /&gt;
Ein Blick in den &amp;quot;Kommentar-Header&amp;quot; verrät, dass von einem externen (HSE) Oszillator von 25MHz ausgegangen wird, der die PLL versorgen soll.&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((25MHz / PLL_M(25)) * PLL_N(336)) / PLL_P(2) = 168MHz&lt;br /&gt;
&lt;br /&gt;
Allerdings stimmt diese Rechnung natürlich nur, wenn wirklich ein 25MHz Quarz am Controller angeschlossen ist. Auf dem STM32F4-Discovery Board befindet sich aber nur ein 8MHz Quarz. Demnach gilt:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((8MHz / PLL_M(25)) * PLL_N(336)) / PLL_P(2) = 53.76MHz&lt;br /&gt;
&lt;br /&gt;
Der Controller läuft also nur mit 53.76MHz, wenn wie ober beschrieben ein Projekt erstellt wird. Allerdings kann dieses Problem durch ändern von den betroffen Defines behoben werden:&lt;br /&gt;
 &lt;br /&gt;
*Dazu geht man in die &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; Datei und passt zur Vollständigkeit erstmal die zum Controller passende Tabelle im &amp;quot;Kommentar-Header&amp;quot; an (Z.57f):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      HSE Frequency(Hz)                      | 8000000&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      PLL_M                                  | 8&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Danach passt man den PPL_M Define (Z.254) an:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/************************* PLL Parameters *************************************/&lt;br /&gt;
/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */&lt;br /&gt;
#define PLL_M      8&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Außerdem muss man den HSE_VALUE Define in der &#039;&#039;&#039;&#039;&#039;inc/stm32f4xx.h&#039;&#039;&#039;&#039;&#039; angepasst werden (Z.122):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#if !defined  (HSE_VALUE)&lt;br /&gt;
  #define HSE_VALUE    ((uint32_t)8000000) /*!&amp;lt; Value of the External oscillator in Hz */&lt;br /&gt;
&lt;br /&gt;
#endif /* HSE_VALUE */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine neue Berechnung zeigt:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((8MHz / PLL_M(8)) * PLL_N(336)) / PLL_P(2) = 168MHz&lt;br /&gt;
&lt;br /&gt;
Jetzt läuft der Controller mit maximaler Geschwindigkeit.&lt;br /&gt;
&lt;br /&gt;
Die Theorie wird durch folgendes Programm verifiziert. Der geviertelte System-Takt SYSCLK wir am Pin PC9 ausgegeben. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);&lt;br /&gt;
&lt;br /&gt;
    GPIO_InitTypeDef GPIOC_InitStructure;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Mode = GPIO_Mode_AF;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_OType = GPIO_OType_PP;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Pin = GPIO_Pin_9;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;&lt;br /&gt;
    GPIO_Init(GPIOC, &amp;amp;GPIOC_InitStructure);&lt;br /&gt;
&lt;br /&gt;
    RCC_MCO2Config(RCC_MCO2Source_SYSCLK, RCC_MCO2Div_4);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Die FPU===&lt;br /&gt;
====Allgemeines====&lt;br /&gt;
STM32F3 und STM32F4 Controller haben eine FPU.&lt;br /&gt;
Damit die FPU richtig verwendet wird, müssen normalerweise zwei Bedingungen erfüllt sein:&lt;br /&gt;
&lt;br /&gt;
1. Der Controller muss die FPU Hardware-seitig aktivieren&lt;br /&gt;
&lt;br /&gt;
2. Damit die FPU auch was zu tuen bekommt, müssen vom Compiler FPU-Instructions erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
Die Em::Blocks IDE verwendet standardmäßig die FPU, wenn eine Vorhanden ist. Hier wird die FPU Hardware-seitig aktiviert (&#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; Z.341):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* FPU settings ------------------------------------------------------------*/&lt;br /&gt;
  #if (__FPU_PRESENT == 1) &amp;amp;&amp;amp; (__FPU_USED == 1)&lt;br /&gt;
    SCB-&amp;gt;CPACR |= ((3UL &amp;lt;&amp;lt; 10*2)|(3UL &amp;lt;&amp;lt; 11*2));  /* set CP10 and CP11 Full Access */&lt;br /&gt;
  #endif&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
__FPU_PRESENT wird in der &#039;&#039;&#039;&#039;&#039;stm32f4xx.h&#039;&#039;&#039;&#039;&#039; definiert.&lt;br /&gt;
__FPU_USED wird von der IDE übernommen (siehe Build-Log): &#039;&#039;&#039;&#039;&#039;-D__FPU_USED&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Außerdem wird der Compiler von der IDE standardmäßig mit dem Argument &#039;&#039;&#039;&#039;&#039;-mfloat-abi=hard&#039;&#039;&#039;&#039;&#039; aufgerufen, wodurch FPU-Instructions erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
====FPU abschalten====&lt;br /&gt;
Um die FPU ab zu schalten (Mir würde jetzt nur Strom sparen als Grund einfallen) geht man wie folgt vor:&lt;br /&gt;
&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; Device -&amp;gt; Policy&#039;&#039;&#039;&#039;&#039; wählt man &#039;&#039;&#039;&#039;&#039;Use target settings&#039;&#039;&#039;&#039;&#039; und über nimmt die Einstellungen, die vorher dort eingetragen waren, allerdings lässt man das Feld &#039;&#039;&#039;&#039;&#039;FP-hardware&#039;&#039;&#039;&#039;&#039; frei.&lt;br /&gt;
&lt;br /&gt;
[[Datei:fpu_1.png|FPU Abschalten Schritt 1]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;Compiler Settings -&amp;gt; Policy&#039;&#039;&#039;&#039;&#039; wählt man dann &#039;&#039;&#039;&#039;&#039;Use target options only&#039;&#039;&#039;&#039;&#039;. Dann kann man unter &#039;&#039;&#039;&#039;&#039;Categories&#039;&#039;&#039;&#039;&#039; die Option &#039;&#039;&#039;&#039;&#039;ARM FPU architecture&#039;&#039;&#039;&#039;&#039; auswählen. Dort stehen dann drei Möglichkeiten für die FPU zur Verfügung:&lt;br /&gt;
&lt;br /&gt;
1. Software-FPU-Library für Gleitkomma-Berechnung verwenden - Keine FPU-Instructions werden generiert (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=soft&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
2. Eine Mischung aus Software- und Hardware-FPU wird verwendet (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=softfp&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
3. Hardware-FPU wird für Gleitkomma-Berechnungen verwendet (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=hard&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
[[Datei:fpu_2.png|FPU Abschalten Schritt 2]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Um die FPU ab zu schalten wählt man natürlich die erste Möglichkeit.&lt;br /&gt;
Bei der 2. und 3. Möglichkeit fügt die IDE auch den Define &#039;&#039;&#039;&#039;&#039;__FPU_USED&#039;&#039;&#039;&#039;&#039; hinzu. Bei Der ersten Möglichkeit nicht. Der Code muss also nicht verändert / auskommentiert werden.&lt;br /&gt;
&lt;br /&gt;
Um die FPU wieder zu aktivieren müssen alle Schritte wieder rückgängig gemacht werden.&lt;br /&gt;
&lt;br /&gt;
Am besten ist es einfach mal alle Möglichkeiten im Einzelschritt durch zu probieren. Dann stellt man schnell fest, ob die FPU aktiviert wir oder nicht. Ein Blick in den erweiterten &#039;&#039;&#039;&#039;&#039;Build-Log&#039;&#039;&#039;&#039;&#039; gibt auch schnell Aufschluss darüber, wie der Compiler aufgerufen wird (siehe Kapitel [http://www.mikrocontroller.net/articles/STM32_-_Einstieg_mit_Em::Blocks#Compilieren Compilieren]).&lt;br /&gt;
&lt;br /&gt;
====Test Programm für die FPU====&lt;br /&gt;
Hier ein kleines Testprogramm, dass misst wie viele Taktzyklen für eine Gleitkomma-Multiplikation gebraucht werden. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define CORE_SysTickEn()    (*((u32*)0xE0001000)) = 0x40000001&lt;br /&gt;
#define CORE_SysTickDis()   (*((u32*)0xE0001000)) = 0x40000000&lt;br /&gt;
#define CORE_GetSysTick()   (*((u32*)0xE0001004))&lt;br /&gt;
&lt;br /&gt;
uint32_t t1, t2, dt;&lt;br /&gt;
float x, y, z;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    x = 53.64f;&lt;br /&gt;
    y = 0.27f;&lt;br /&gt;
&lt;br /&gt;
    CORE_SysTickEn();&lt;br /&gt;
    t1 = CORE_GetSysTick();&lt;br /&gt;
&lt;br /&gt;
    z = x * y;&lt;br /&gt;
&lt;br /&gt;
    t2 = CORE_GetSysTick();&lt;br /&gt;
    CORE_SysTickDis();&lt;br /&gt;
&lt;br /&gt;
    dt = (t2 - t1) - 9; //9 Takt-Zyklen werden für die Messung gebraucht &lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Booten aus dem SRAM==&lt;br /&gt;
STM32 Controller haben die Möglichkeit Code aus dem Flash als auch aus dem SRAM auszuführen. Um eine Anwenung per Debugger in des SRAM zu laden sind nur wenige Schritte erforderlich:&lt;br /&gt;
&lt;br /&gt;
*Um das Linkerscript für den SRAM zu verwenden geht man zu: &#039;&#039;&#039;&#039;&#039;Build options... -&amp;gt; Device&#039;&#039;&#039;&#039;&#039; dort wählt man unter &#039;&#039;&#039;&#039;&#039;Policy&#039;&#039;&#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;Use target settings&#039;&#039;&#039;&#039;&#039; aus und übernimmt die vorherigen Einstellungen, nur unter &#039;&#039;&#039;&#039;&#039;Linker script*&#039;&#039;&#039;&#039;&#039; gibt man &#039;&#039;&#039;&#039;&#039;.\stm32f407vg_sram.ld&#039;&#039;&#039;&#039;&#039; an&lt;br /&gt;
&lt;br /&gt;
*Dann muss man noch unter &#039;&#039;&#039;&#039;&#039;Debug -&amp;gt; Interfaces -&amp;gt; Settings&#039;&#039;&#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;Vector table start&#039;&#039;&#039;&#039;&#039; auf 0x20000000 ändern und &#039;&#039;&#039;&#039;&#039;Execute from RAM&#039;&#039;&#039;&#039;&#039; auswählen.&lt;br /&gt;
&lt;br /&gt;
Anschließend kann man die Anwendung ganz normal debuggen. Nach einem Reset muss die Anwenung erneut mit dem Debugger gestartet werden.&lt;br /&gt;
&lt;br /&gt;
=Fortsetzung folgt..=&lt;br /&gt;
Kritik, Wünsche usw. sind gerne erwünscht, am besten hier in den Thread posten: [http://www.mikrocontroller.net/topic/323750 Neues STM32 Tutorial]&lt;br /&gt;
&lt;br /&gt;
[[Category:ARM]]&lt;br /&gt;
[[Category:STM32]]&lt;/div&gt;</summary>
		<author><name>Avrprogger</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=STM32_-_Einstieg_mit_Em::Blocks&amp;diff=81546</id>
		<title>STM32 - Einstieg mit Em::Blocks</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=STM32_-_Einstieg_mit_Em::Blocks&amp;diff=81546"/>
		<updated>2014-02-11T16:43:17Z</updated>

		<summary type="html">&lt;p&gt;Avrprogger: dfg&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In diesem Tutorial werde ich versuchen, möglichst einfach, die ersten Schritte zur Entwicklung von STM32 Anwenungen mit der Em::Blocks IDE zu erklären. Hier soll nicht so stark auf die einzelnen Peripherie-Module der Controller eingegangen werden, sondern mehr auf die IDE und die verschieden Libraries, wie die CMSIS Library, die DSP-Library, die Standard-Peripheral-Library, die USB-Library und vllt. über Ethernet. Ich denke ein Kapitel zu FreeRTOS wird es auch geben. Auserdem steht im Vordergrund Sachen wie z.B. booten aus dem SRAM, In-Application-Programming, FPU, Core-Coupled-RAM usw. Mal sehn wie weit ich komme ;)&lt;br /&gt;
&lt;br /&gt;
==Die Entwicklungsumgebung==&lt;br /&gt;
===Hardware===&lt;br /&gt;
Zum testen der Anwendungen, benutze ich das STM32F4-Discovery Board, welches einen Debugger, Peripherie und natürlich einen STM32 Controller (STM32F407VGT6) enthält. Deshalb sind alle Beispiele hier für den STM32F407VG Controller ausgelegt, können aber meisten 1:1 auf andere Controller portiert werden. Ich werde auch möglichsts keine STM32F4-Discovery Board spezifischen Libraries verwenden, damit der Portierungs-Vorgang möglichsts einfach bleibt.&lt;br /&gt;
&lt;br /&gt;
===Software===&lt;br /&gt;
In diesem Tutorial verwende ich [http://www.emblocks.org/ Em::Blocks] als IDE. Em::Blocks ist eine kostenlose, uneingeschränkte IDE, die alle STM32 Mikrcontroller unterstützt und sehr einfach zu bedienen ist.&lt;br /&gt;
nach dem Download kann die IDE per Dialog, sehr einfach, installiert werden. Als Compiler beinhaltet Em::Blocks den &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
Die IDE unterstützt zurzeit den ST-Link, den J-Link und es gibt eine Generic-Vorlage, durch welche andere Debugger konfiguriert werden können.&lt;br /&gt;
&lt;br /&gt;
Außerdem muss noch der passende Treiber für den Debugger installiert werden. Verwendet man ein Discovery-Board muss der [http://www.st.com/web/catalog/tools/FM146/CL1984/SC724/SS1677/PF251168 ST-Link/V2]-Treiber heruntergeladen und installiert werden. (Die Installation muss evtl. als Administrator ausgeführt werden, da sonst die Installation unvollständig wird.) Nach der Installation des Treibers kann man den Debugger über die entsprechende USB Schnittstelle an den PC anschließen und es sollte die Meldung von Windows kommen, dass der richtige Treiber gefunden wurde.&lt;br /&gt;
&lt;br /&gt;
===Libraries===&lt;br /&gt;
Zum programmieren benötigt man noch die [http://www.arm.com/products/processors/cortex-m/cortex-microcontroller-software-interface-standard.php CMSIS] und die Standard-Peripheral-Library (z.B. für die F4 Controller [http://www.st.com/stonline/stappl/productcatalog/app?page=partNumberSearchPage&amp;amp;levelid=SS1577&amp;amp;parentid=1743&amp;amp;resourcetype=SW Standard-Peripheral-Library-F4]), die man am besten in einen Ordner (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\STM32&#039;&#039;&#039;&#039;&#039;) entpackt&lt;br /&gt;
&lt;br /&gt;
==Basis-Wissen zur IDE==&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von Dateien zum Projekt===&lt;br /&gt;
Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf &amp;lt;ProjektName&amp;gt; -&amp;gt; Add files...&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Enfernen von Dateien aus dem Projekt===&lt;br /&gt;
Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf die Datei / mehrere Dateien auswählen -&amp;gt; Remove file from project&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
Die Dateien werden lediglich aus dem Projekt entfernt und nicht von der Festplatte gelöscht.&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von Include-Pfaden===&lt;br /&gt;
Sofern die Include-Datei(en) nicht im standard Include-Ordner &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; des Projektes liegen, muss man den Pfad zum Projekt hinzufügen, damit der Compiler die Include-Dateien später auch finden kann. Man geht wie folgt vor: Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; Search Directories -&amp;gt; Add&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von globalen Defines zum Build===&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; #defines&#039;&#039;&#039;&#039;&#039; können globale Defines hinzugefügt werden.&lt;br /&gt;
&lt;br /&gt;
===Compilieren===&lt;br /&gt;
Entweder über das &#039;&#039;&#039;&#039;&#039;Build&#039;&#039;&#039;&#039;&#039; Menü oder über &#039;&#039;&#039;&#039;&#039;F7&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Um eine genau Ausgabe des Compiler-Aufrufes mit allen Argumenten zu bekommen, geht man im &#039;&#039;&#039;&#039;&#039;Settings&#039;&#039;&#039;&#039;&#039; Menü auf &#039;&#039;&#039;&#039;&#039;Tools...&#039;&#039;&#039;&#039;&#039; und dann auf &#039;&#039;&#039;&#039;&#039;Toolchain executables&#039;&#039;&#039;&#039;&#039;. Ganz unten, unter &#039;&#039;&#039;&#039;&#039;Logging&#039;&#039;&#039;&#039;&#039; kann man dann &#039;&#039;&#039;&#039;&#039;Full command line&#039;&#039;&#039;&#039;&#039; auswählen.&lt;br /&gt;
&lt;br /&gt;
====Compiler Optionen====&lt;br /&gt;
=====Optimierung=====&lt;br /&gt;
Standardmäßig verwendet Em::Blocks keine Optimierung. Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; Categories: Optimization&#039;&#039;&#039;&#039;&#039; kann zwischen verschieden Optimierungen ausgewählt werden.&lt;br /&gt;
&lt;br /&gt;
=====Verschiedene C-Standards=====&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; Categories: Language standard&#039;&#039;&#039;&#039;&#039; kann man zwischen verschieden C-Standard auswählen, wie z.B, C99.&lt;br /&gt;
(Mit C99 können auch die Lauf-Variable in der for-Schleife deklariert werden: for(int i;..))&lt;br /&gt;
&lt;br /&gt;
===Debuggen===&lt;br /&gt;
*Als erstes den Debugger starten über das &#039;&#039;&#039;&#039;&#039;Debug&#039;&#039;&#039;&#039;&#039; Menü und &#039;&#039;&#039;&#039;&#039;Start/stop Debug Session&#039;&#039;&#039;&#039;&#039; oder über &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
*Danach läuft die Anwendung auf dem Controller und warten im &#039;&#039;&#039;&#039;&#039;Reset_Handler&#039;&#039;&#039;&#039;&#039; auf Einzelschritt- bzw. Run- Befehle (&#039;&#039;&#039;&#039;&#039;F5, F10, F11&#039;&#039;&#039;&#039;&#039; usw..(siehe &#039;&#039;&#039;&#039;&#039;Debug-Menü&#039;&#039;&#039;&#039;&#039; für alle Möglichkeiten))&lt;br /&gt;
&lt;br /&gt;
*Mit &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039; wird die Debug-Session auch wieder beendet&lt;br /&gt;
&lt;br /&gt;
*Unter &#039;&#039;&#039;&#039;&#039;Debug -&amp;gt; Interfaces -&amp;gt; Target settings&#039;&#039;&#039;&#039;&#039; können Eigenschaften, wie z.B &#039;&#039;&#039;&#039;&#039;Run to main()&#039;&#039;&#039;&#039;&#039; aktiviert werden.&lt;br /&gt;
&lt;br /&gt;
===Projekt als Template abspeichern===&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;File -&amp;gt; Save project as template...&#039;&#039;&#039;&#039;&#039;. Das Template erscheint dann im Projekt-Dialog unter &#039;&#039;&#039;&#039;&#039;User templates&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Das erste Projekt erstellen==&lt;br /&gt;
Hier erkläre ich, wie man am Besten (aus meiner Sicht), ein neues Projekt von Grund auf erstellt, sodass man hinterher, den Controller-Kern über die CMSIS-Library und die Peripherie über die Register steuern kann.&lt;br /&gt;
&lt;br /&gt;
===1. Projekt mit der IDE erstellen===&lt;br /&gt;
Nach der Installation der oben beschriebenen Komponenten erstellt man am besten ein Verzeichnis (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\EmBlocks&#039;&#039;&#039;&#039;&#039;), indem später alle Projekte gespeichert werden. Für Libraries kann man auch noch ein Verzeichnis (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\STM32&#039;&#039;&#039;&#039;&#039;) erstellen, wo alle Libraries gespeichert werden, die man für die Projekt brauchen.&lt;br /&gt;
&lt;br /&gt;
Als nächstes starten man EmBlocks. Bei dem ersten Start öffnet sich ein Fenster, wo verschiedene Compiler angezeigt werden, die Em::Blocks findet. Dort wählt man den &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039; aus und klickt &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039;. Nun sollte sich das Hauptfenster von Em::Blocks öffnen. Über &#039;&#039;&#039;&#039;&#039;Create a new Project&#039;&#039;&#039;&#039;&#039; oder &#039;&#039;&#039;&#039;&#039;File -&amp;gt; New -&amp;gt; Project&#039;&#039;&#039;&#039;&#039; ruft man den Projekt-Dialog auf und kann ein neues Projekt erzeugen.&lt;br /&gt;
&lt;br /&gt;
Auf der Ersten Seite wählen man den &#039;&#039;&#039;&#039;&#039;STmicro-ARM&#039;&#039;&#039;&#039;&#039; Projekt-Typ aus.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_1.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auf der nächsten Seite wird man darauf hingewiesen, dass das der entsprechende Projekt-Typ-Dialog ausgeführt wird. Hier kann man ein Häkchen bei &#039;&#039;&#039;&#039;&#039;Skip this page next time&#039;&#039;&#039;&#039;&#039; setzen und auf &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; klicken.&lt;br /&gt;
&lt;br /&gt;
Im nächsten Schritt wählen man das zuvor erstellt Verzeichnis unter &#039;&#039;&#039;&#039;&#039;Folder to create Project in&#039;&#039;&#039;&#039;&#039; aus, indem später alle Projekt gespeichert werden. Außerdem geben wir dem Projekt einen Namen (z.B. &#039;&#039;&#039;&#039;&#039;FirstProject&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_2.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danach muss man einen Compiler auswählen und bestimmen, welche Projekt-Konfigurationen erszeugt werden sollen. Unter &#039;&#039;&#039;&#039;&#039;Compiler&#039;&#039;&#039;&#039;&#039; wählt man &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039; und man kann das Häkchen bei &#039;&#039;&#039;&#039;&#039;Create &amp;quot;Release&amp;quot; configuration&#039;&#039;&#039;&#039;&#039; entfernen, da diese unnötig ist, die Debug-Konfiguration sollte eig. immer ausreichen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_3.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auf den folgenden Seite wird der Controller ausgewählt. Verwendet man ein STM32F4-Discovery Board müssen folgende Dinge gewählt werden: &#039;&#039;&#039;&#039;&#039;Cortex_M4 (F3xx - F4xx) -&amp;gt; STM32F4xx (Cortex M4 with FPU) -&amp;gt; STM32F407VG&#039;&#039;&#039;&#039;&#039;. Leider sind die Auswahl Möglichkeiten nicht ganz richtig, da auch die F3 Controller einen Cortex M4 Kern und eine FPU haben (Ist aber nicht so wichtig, ist nur eine formale Sache). Außerdem entfernt man das Häkchen bei &#039;&#039;&#039;&#039;&#039;Standard Peripherals Library&#039;&#039;&#039;&#039;&#039; (Wie man die Standard-Peripheral-Library einbindet und verwendet erkläre ich später). Man kann auch das Häkchen bei &#039;&#039;&#039;&#039;&#039;Create hex file for Realease target&#039;&#039;&#039;&#039;&#039; entfernen.&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;Stack Size&#039;&#039;&#039;&#039;&#039; und &#039;&#039;&#039;&#039;&#039;Heap Size&#039;&#039;&#039;&#039;&#039; wird die Größe von Stack und Heap festgelegt. Für eine erste Anwendung kann man die Einstellungen so lassen (Stack-Size: 0x0100 =&amp;gt; 256 Byte Stack und Heap-Size: 0x0000 =&amp;gt; kein Heap). Mit &#039;&#039;&#039;&#039;&#039;Finish&#039;&#039;&#039;&#039;&#039; ist der Projekt Dialog abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_4.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danach sollten sich zwei neue Fenster öffnen, um die Debug-Eigenschaften fest zu legen.&lt;br /&gt;
Verwendet man ein Discovery Board/ST-Link müssen die Einstellungen wie auf dem Bild gewählt werden. Über den Button &#039;&#039;&#039;&#039;&#039;Settings&#039;&#039;&#039;&#039;&#039; öffnet sich das zweite Fenster, falls sich dieses nicht schon von alleine öffnen sollte. Nach den Schließen der Fenster über &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; ist der Projekt Dialog beendet und ein neues Projekt steht zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_5_1.png|Debug Eigenschaften 1. Fenster]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_5_2.png|Debug Eigenschaften 2. Fenster]]&lt;br /&gt;
&lt;br /&gt;
===2. CMSIS-Library und Startup-Code hinzufügen===&lt;br /&gt;
Wenn man sich, nachdem man ein neues Projekt in der IDE erstellt hat, die bereits vorhandenen Dateien im Projekt ansieht, stellt man fest, das bereits ein Ordner &#039;&#039;&#039;&#039;&#039;cmsis&#039;&#039;&#039;&#039;&#039; existiert, der einige wichtige Include-Dateien der CMSIS-Library enthält. Allerdings sind das wirklich nur die wichtigsten Include-Dateien der CMSIS-Library und dazu noch, die aus einer älternen Version. Ich ziehe es deshalb vor die &amp;quot;Mini-CMSIS-Libraray&amp;quot; und die &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c/.h&#039;&#039;&#039;&#039;&#039; Dateien des Projektes durch aktuellere Versionen zu ersetzen. So ist später auch die Integration  von anderen Libraries, wie z.B. der CMSIS-DSP-Libarary einfacher.  &lt;br /&gt;
&lt;br /&gt;
Zunächst gehen man in das Projekt-Verzeichnis und löscht:&lt;br /&gt;
*Den Ordner &#039;&#039;&#039;&#039;&#039;cmsis&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Alle Dateien im Include Verzeichnis &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; im &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner&lt;br /&gt;
&lt;br /&gt;
Außerdem entfernt man auch alle gelöschten Dateien in der IDE aus dem Projekt mit &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Rechts Klick -&amp;gt; Remove file from project&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Es sollte folgende Verzeichnis Struktur überbleiben:&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_6.png|Überbleibende Dateien]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Jetzt müssen die gelöschten Dateien durch die aktuelleren ersetzt werden.&lt;br /&gt;
&lt;br /&gt;
*Dazu kopieren man den gesamten Ordner &#039;&#039;&#039;&#039;&#039;CMSIS&#039;&#039;&#039;&#039;&#039; aus dem CMSIS Download in das Projekt Verzeichnis.&lt;br /&gt;
&lt;br /&gt;
*Aus dem Standard-Peripheral-Library Download kopiert man von &#039;&#039;&#039;&#039;&#039;Libraries\CMSIS\Device\ST\STM32F4xx\Include&#039;&#039;&#039;&#039;&#039; alle Dateien in den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projekt Verzeichnisses&lt;br /&gt;
&lt;br /&gt;
*Aus der Standard-Peripheral-Library kopieren man ebenfalls von &#039;&#039;&#039;&#039;&#039;Libraries\CMSIS\Device\ST\STM32F4xx\Source\Templates&#039;&#039;&#039;&#039;&#039; die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; in den &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner des Projekts&lt;br /&gt;
&lt;br /&gt;
Anschließend müssen die neuen Dateien in der IDE dem Projekt hinzugefügt werden. Dazu benutzt man &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Rechts Klick -&amp;gt; Add files&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
*Aus dem &#039;&#039;&#039;&#039;&#039;CMSIS&#039;&#039;&#039;&#039;&#039; Ordner im Projekt Verzeichnis werden aus den Unterorder &#039;&#039;&#039;&#039;&#039;Include&#039;&#039;&#039;&#039;&#039; folgende Dateien dem Projekt hinzugefügt:&lt;br /&gt;
**arm_common_tables.h&lt;br /&gt;
**arm_const_structs.h&lt;br /&gt;
**arm_math.h&lt;br /&gt;
**core_cm4.h&lt;br /&gt;
**core_cm4_simd.h&lt;br /&gt;
**core_cmFunc.h&lt;br /&gt;
**core_cmInstr.h&lt;br /&gt;
*Alle Dateien aus den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projektes&lt;br /&gt;
*Die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; aus dem &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner&lt;br /&gt;
&lt;br /&gt;
So sollte die Struktur dann aussehen:&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_7.png|Anwenungs-Grundgerüst]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Da einige Dateien der Libraries später bearbeitet werden müssen und Schreibgeschützt sind, weise ich hier schonmal darauf hin, das der Schreibschutz in der IDE über &#039;&#039;&#039;&#039;&#039;Rechts Klick auf die Datei -&amp;gt; Properties -&amp;gt; Häkchen bei &amp;quot;File is read only&amp;quot; entfernen&#039;&#039;&#039;&#039;&#039; entfert werden kann.&lt;br /&gt;
&lt;br /&gt;
Damit die IDE die Header-Dateien der CMSIS Library auch finden kann, weil diese ja nicht im standard Include Ordner &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; liegen, muss unter &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Build Options -&amp;gt; Search Directories&#039;&#039;&#039;&#039;&#039; der Pfad &#039;&#039;&#039;&#039;&#039;CMSIS\Include&#039;&#039;&#039;&#039;&#039; hinzugefügt werden.&lt;br /&gt;
&lt;br /&gt;
Compiliert man jetzt das Projekt mit &#039;&#039;&#039;&#039;&#039;F7&#039;&#039;&#039;&#039;&#039; gibt es ein paar Fehler Meldungen, weil keine Controller-Reihe ausgewählt wurde. Ebenfalls unter &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Build Options -&amp;gt; Compiler Settings -&amp;gt; #defines&#039;&#039;&#039;&#039;&#039; wird der Define &#039;&#039;&#039;&#039;&#039;STM32F40_41xxx&#039;&#039;&#039;&#039;&#039; hinzugefügt.&lt;br /&gt;
&lt;br /&gt;
Beim erneuten Compilieren sollten sich nun keine neuen Fehler ergeben.&lt;br /&gt;
&lt;br /&gt;
===3. Das erste Programm===&lt;br /&gt;
Nachdem ein grundsätzliches &amp;quot;Gerüst&amp;quot; fertig ist, kann man den ersten Code schreiben.&lt;br /&gt;
main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC-&amp;gt;AHB1ENR |= RCC_AHB1ENR_GPIODEN;    //Takt für GPIO aktivieren&lt;br /&gt;
    GPIOD-&amp;gt;MODER |= GPIO_MODER_MODER15_0;   //GPIOD Pin15 als Ausgang&lt;br /&gt;
    GPIOD-&amp;gt;BSRRL |= GPIO_BSRR_BS_15;        //GPIOD Pin15 auf High ziehen&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039; wird dann der Debugger gestartet. Hat der Debugger das Projekt erfolgreich übertragen kann die Ausführung mit &#039;&#039;&#039;&#039;&#039;F5&#039;&#039;&#039;&#039;&#039; begonnen werden.&lt;br /&gt;
&lt;br /&gt;
==Libraries einbinden/verwenden==&lt;br /&gt;
===Einbinden der Standard-Peripheral-Library===&lt;br /&gt;
Um nicht immer die einzelnen Register, wie im ersten &amp;quot;bare-metal&amp;quot; Beispiel, aus dem Reference-Manual zu suchen und zu beschreiben, gibt es von ST die Standard Peripheral Library, die diese Aufgaben übernimmt und mit der sich die &amp;quot;normale/grundlegende&amp;quot; (Alles außer USB und Ethernet) Peripherie recht einfach steuern lässt. Um die Library zu verwenden erzeugt man wie oben beschrieben ein neues Grundgerüst und kopiert als erstes den Ordner &#039;&#039;&#039;&#039;&#039;Libraries\STM32F4xx_StdPeriph_Driver&#039;&#039;&#039;&#039;&#039; aus dem Standard-Peripheral-Library Download in das Projekt-Verzeichnis. Außerdem muss man die Datei &#039;&#039;&#039;&#039;&#039;Project\STM32F4xx_StdPeriph_Templates\stm32f4xx_conf.h&#039;&#039;&#039;&#039;&#039; ebenfalls aus dem Standard-Peripheral-Library Download in den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projektes kopieren. In der IDE fügt man den Include-Path &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\inc&#039;&#039;&#039;&#039;&#039; hinzufügen, wie bei der CMSIS-Library (s.o.).&lt;br /&gt;
Außerdem muss noch &#039;&#039;&#039;&#039;&#039;USE_STDPERIPH_DRIVER&#039;&#039;&#039;&#039;&#039; als Define in der IDE hinzugefügt werden (s.o.).&lt;br /&gt;
Danach fügt man die Source- und Include-Dateien aus dem Ordner &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\inc&#039;&#039;&#039;&#039;&#039; und &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\src&#039;&#039;&#039;&#039;&#039; dem Project mit &#039;&#039;&#039;&#039;&#039;&amp;lt;Project Name&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Add files&#039;&#039;&#039;&#039;&#039; hinzu, allerdings nur die, für welche auch der Controller die entsprechende Peripherie besitzt. Beim STM32F4-Discovery Board / STM32F407VG Controller dürfen also nicht folgende Dateien nicht mit hinzugefügt werden, weil diese Peripherie nur bei anderen Controller vorhanden ist:&lt;br /&gt;
&lt;br /&gt;
*stm32f4xx_dma2d.c/.h&lt;br /&gt;
*stm32f4xx_fmc.c/.h&lt;br /&gt;
*stm32f4xx_ltdc.c/.h&lt;br /&gt;
*stm32f4xx_sai.c/.h&lt;br /&gt;
&lt;br /&gt;
Daraus resultiert folgende Struktur:&lt;br /&gt;
&lt;br /&gt;
[[Datei:stdperiphlib_2.png|Header-Struktur]] [[Datei:stdperiphlib_1.png|Source-Struktur]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Anschließen kann die Standard-Peripheral-Library benutz werden.&lt;br /&gt;
main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);&lt;br /&gt;
&lt;br /&gt;
    GPIO_InitTypeDef GPIOD_InitStructure;&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Mode = GPIO_Mode_OUT;     //Als Ausgang&lt;br /&gt;
    GPIOD_InitStructure.GPIO_OType = GPIO_OType_PP;    //Push-Pull Betrieb&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Pin = GPIO_Pin_15;        //Pin 15 (STM32F4-Discovery: Blaue LED)&lt;br /&gt;
    GPIOD_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;  //Kein Pull-Up oder Pull-Down Widerstand aktiviert&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Speed = GPIO_Speed_25MHz; //25MHz Update-Rate&lt;br /&gt;
    GPIO_Init(GPIOD, &amp;amp;GPIOD_InitStructure);&lt;br /&gt;
&lt;br /&gt;
    GPIO_SetBits(GPIOD, GPIO_Pin_15);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Einbinden der DSP-Library===&lt;br /&gt;
STM32F3 / STM32F4 Microcontroller haben neben der FPU noch einen Digital-Signal-Processor (DSP). Die DSP dient hauptsächlich dazu, viele Daten schnell zu verarbeiten (z.B. Video- oder Audiosignal). Der CMSIS-Download beinhaltet dazu neben der eigentlichen CMSIS-Library auch noch eine DSP-Library. Diese Library stellt sowohl einfache, mathematische Funktionen wie addieren, multiplizieren usw. als auch komplexe Funktionen, wie z.B  einen IIR-Filter, zur Verfügung. Die DSP-Library ist weiter aufgeteilt in kleinere Module, wie z.B. BasicMathFunctions, FilteringFunctions usw. (siehe &#039;&#039;&#039;&#039;&#039;CMSIS\DSP-Library\Source&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
Um die DSP-Library zu verwenden müssen nur die Source-Files des benötigten Moduls einbinden.&lt;br /&gt;
(&#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Add files...&#039;&#039;&#039;&#039;&#039;). Außerdem muss in der &#039;&#039;&#039;&#039;&#039;main.c&#039;&#039;&#039;&#039;&#039; der Include &#039;&#039;&#039;&#039;&#039;arm_math.h&#039;&#039;&#039;&#039;&#039; eingebunden werden. Aus irgendeinem Grund gibt es dann jedoch die Warnung: &amp;quot;Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)&amp;quot;. Ich hab noch nicht rausgefunden, wieso diese Warnung auftaucht. Die Warnung verschwindet, wenn man in der &#039;&#039;&#039;&#039;&#039;Build options...&#039;&#039;&#039;&#039;&#039; das Define &#039;&#039;&#039;&#039;&#039;__FPU_PRESENT&#039;&#039;&#039;&#039;&#039; hinzufügt (Ich weiß selber das das keine schöne Lösung ist, eine andere hab ich jedoch noch nicht gefunden). Jetzt kann die DSP-Library verwedet werden. Das Beispiel multipliziert zwei Buffer miteinander. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
#include &amp;quot;arm_math.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    float32_t x[1024];&lt;br /&gt;
    float32_t y[1024];&lt;br /&gt;
    float32_t z[1024];&lt;br /&gt;
&lt;br /&gt;
    for(uint16_t i = 0; i &amp;lt; 1024; i++)&lt;br /&gt;
    {&lt;br /&gt;
        x[i] = i;&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for(uint16_t i = 0; i &amp;lt; 1024; i++)&lt;br /&gt;
    {&lt;br /&gt;
        y[i] = PI;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    arm_mult_f32(x, y, z, 1024);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Startup-Code, Linker-Script, Takt, FPU usw.==&lt;br /&gt;
===Startup-Code===&lt;br /&gt;
Em::Blocks fügt standardmäßig einen Startup-Code mit in das Projekt ein. Die wichtigsten Dinge die darin erledigt werden sind folgende:&lt;br /&gt;
&lt;br /&gt;
*Stack und Heap wird angelgt&lt;br /&gt;
*Die Vector-Table wird angelegt&lt;br /&gt;
*Ein Default Reset-Handler wird implementiert, dieser erledigt folgende aufgaben:&lt;br /&gt;
**Kopieren der definierten Daten aus dem Flash in den SRAM&lt;br /&gt;
**&#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; wird aufgerfen, wenn &#039;&#039;&#039;&#039;&#039;__NO_SYSTEM_INIT&#039;&#039;&#039;&#039;&#039; nicht definiert ist&lt;br /&gt;
**Sprung in die &#039;&#039;&#039;&#039;&#039;main()&#039;&#039;&#039;&#039;&#039; Funktion&lt;br /&gt;
*Allen anderen Interrupt-Handler wird eine Default-Funktion &#039;&#039;&#039;&#039;&#039;def_irq_handler&#039;&#039;&#039;&#039;&#039; mit einer &#039;&#039;&#039;&#039;&#039;while(1)&#039;&#039;&#039;&#039;&#039;-Schleife zugewiesen, falls kein anderer Interrupt-Handler existiert.&lt;br /&gt;
&lt;br /&gt;
Normalerweise muss am Startup-Code nichts verändert werden.&lt;br /&gt;
&lt;br /&gt;
===Linker-Script===&lt;br /&gt;
Em::Blocks stellt zwei fertige Linker-Scripts bereit, eins für die Ausführung des Programmes aus dem Flash (&#039;&#039;&#039;&#039;&#039;*_flash.ld&#039;&#039;&#039;&#039;&#039;), das andere für die Ausführung aus dem SRAM (&#039;&#039;&#039;&#039;&#039;*_sram.ld&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Normalerweise muss auch hier nichts geändert werden, es sei den Daten sollen in bestimmten Adressbereichen abgelegt werden (z.B. im Core-Coupled RAM), was ich später noch zum Tutorial hinzufüge.&lt;br /&gt;
&lt;br /&gt;
===Der Takt===&lt;br /&gt;
Jeder Controller oder Prozessor braucht einen Takt, indem er die einzelnen Maschinen-Befehle abarbeiten kann.&lt;br /&gt;
Bei den STM32 Mikrocontrollern kann dieser Takt aus verschiedenen Quellen kommen:&lt;br /&gt;
&lt;br /&gt;
1. High Speed Internal Oszillator (HSI)&lt;br /&gt;
&lt;br /&gt;
2. High Speed External Oszillator (HSE)&lt;br /&gt;
&lt;br /&gt;
3. Low Speed Internal Oszillator (LSI)&lt;br /&gt;
&lt;br /&gt;
4. Low Speed External Oszillator (LSE)&lt;br /&gt;
&lt;br /&gt;
5. Phase-Locked Loop (PLL) (generiert den Takt aus den ersten vier Taktquellen durch Teiler und Faktoren)&lt;br /&gt;
&lt;br /&gt;
Nach einem Reset wird der Controller aus der HSI Taktquelle versorgt (16MHz beim STM32F407VG). Um die voll Performance des Controllers zu erreichen muss die PLL verwendet werden, welche den Takt durch geschickte Teiler und Faktoren vervielfältigt, sodass am Ende der Controller mit der maximalen Taktfrequenz läuft. Die notwendige Initialisierung der PLL findet in der Funktion &#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; statt. Die PLL erzeugt zunächst einen Basistakt:&lt;br /&gt;
&lt;br /&gt;
PLL_VCO = (F_HSE / PLL_M) * PLL_N&lt;br /&gt;
&lt;br /&gt;
Aus diesem Takt wird dann der Takt für den Controller-Kern abgeleitet:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = PLL_VCO / PLL_P&lt;br /&gt;
&lt;br /&gt;
Und der Takt für SDIO / USB / RNG (48MHz):&lt;br /&gt;
&lt;br /&gt;
48MHz = PLL_VCO / PLL_Q&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Durch weiter Teiler werden, die Takte für die einzelnen Busse erzeugt, da diese nicht alle beliebig schnell betrieben werden dürfen.&lt;br /&gt;
&lt;br /&gt;
Genaue Angaben findet man zu dem jeweiligen Clock-System des Controllers im Reference Manual.&lt;br /&gt;
&lt;br /&gt;
Ein Blick in den &amp;quot;Kommentar-Header&amp;quot; verrät, dass von einem externen (HSE) Oszillator von 25MHz ausgegangen wird, der die PLL versorgen soll.&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((25MHz / PLL_M(25)) * PLL_N(336)) / PLL_P(2) = 168MHz&lt;br /&gt;
&lt;br /&gt;
Allerdings stimmt diese Rechnung natürlich nur, wenn wirklich ein 25MHz Quarz am Controller angeschlossen ist. Auf dem STM32F4-Discovery Board befindet sich aber nur ein 8MHz Quarz. Demnach gilt:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((8MHz / PLL_M(25)) * PLL_N(336)) / PLL_P(2) = 53.76MHz&lt;br /&gt;
&lt;br /&gt;
Der Controller läuft also nur mit 53.76MHz, wenn wie ober beschrieben ein Projekt erstellt wird. Allerdings kann dieses Problem durch ändern von den betroffen Defines behoben werden:&lt;br /&gt;
 &lt;br /&gt;
*Dazu geht man in die &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; Datei und passt zur Vollständigkeit erstmal die zum Controller passende Tabelle im &amp;quot;Kommentar-Header&amp;quot; an (Z.57f):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      HSE Frequency(Hz)                      | 8000000&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      PLL_M                                  | 8&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Danach passt man den PPL_M Define (Z.254) an:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/************************* PLL Parameters *************************************/&lt;br /&gt;
/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */&lt;br /&gt;
#define PLL_M      8&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Außerdem muss man den HSE_VALUE Define in der &#039;&#039;&#039;&#039;&#039;inc/stm32f4xx.h&#039;&#039;&#039;&#039;&#039; angepasst werden (Z.122):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#if !defined  (HSE_VALUE)&lt;br /&gt;
  #define HSE_VALUE    ((uint32_t)8000000) /*!&amp;lt; Value of the External oscillator in Hz */&lt;br /&gt;
&lt;br /&gt;
#endif /* HSE_VALUE */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine neue Berechnung zeigt:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((8MHz / PLL_M(8)) * PLL_N(336)) / PLL_P(2) = 168MHz&lt;br /&gt;
&lt;br /&gt;
Jetzt läuft der Controller mit maximaler Geschwindigkeit.&lt;br /&gt;
&lt;br /&gt;
Die Theorie wird durch folgendes Programm verifiziert. Der geviertelte System-Takt SYSCLK wir am Pin PC9 ausgegeben. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);&lt;br /&gt;
&lt;br /&gt;
    GPIO_InitTypeDef GPIOC_InitStructure;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Mode = GPIO_Mode_AF;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_OType = GPIO_OType_PP;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Pin = GPIO_Pin_9;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;&lt;br /&gt;
    GPIO_Init(GPIOC, &amp;amp;GPIOC_InitStructure);&lt;br /&gt;
&lt;br /&gt;
    RCC_MCO2Config(RCC_MCO2Source_SYSCLK, RCC_MCO2Div_4);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Die FPU===&lt;br /&gt;
====Allgemeines====&lt;br /&gt;
STM32F3 und STM32F4 Controller haben eine FPU.&lt;br /&gt;
Damit die FPU richtig verwendet wird, müssen normalerweise zwei Bedingungen erfüllt sein:&lt;br /&gt;
&lt;br /&gt;
1. Der Controller muss die FPU Hardware-seitig aktivieren&lt;br /&gt;
&lt;br /&gt;
2. Damit die FPU auch was zu tuen bekommt, müssen vom Compiler FPU-Instructions erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
Die Em::Blocks IDE verwendet standardmäßig die FPU, wenn eine Vorhanden ist. Hier wird die FPU Hardware-seitig aktiviert (&#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; Z.341):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* FPU settings ------------------------------------------------------------*/&lt;br /&gt;
  #if (__FPU_PRESENT == 1) &amp;amp;&amp;amp; (__FPU_USED == 1)&lt;br /&gt;
    SCB-&amp;gt;CPACR |= ((3UL &amp;lt;&amp;lt; 10*2)|(3UL &amp;lt;&amp;lt; 11*2));  /* set CP10 and CP11 Full Access */&lt;br /&gt;
  #endif&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
__FPU_PRESENT wird in der &#039;&#039;&#039;&#039;&#039;stm32f4xx.h&#039;&#039;&#039;&#039;&#039; definiert.&lt;br /&gt;
__FPU_USED wird von der IDE übernommen (siehe Build-Log): &#039;&#039;&#039;&#039;&#039;-D__FPU_USED&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Außerdem wird der Compiler von der IDE standardmäßig mit dem Argument &#039;&#039;&#039;&#039;&#039;-mfloat-abi=hard&#039;&#039;&#039;&#039;&#039; aufgerufen, wodurch FPU-Instructions erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
====FPU abschalten====&lt;br /&gt;
Um die FPU ab zu schalten (Mir würde jetzt nur Strom sparen als Grund einfallen) geht man wie folgt vor:&lt;br /&gt;
&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; Device -&amp;gt; Policy&#039;&#039;&#039;&#039;&#039; wählt man &#039;&#039;&#039;&#039;&#039;Use target settings&#039;&#039;&#039;&#039;&#039; und über nimmt die Einstellungen, die vorher dort eingetragen waren, allerdings lässt man das Feld &#039;&#039;&#039;&#039;&#039;FP-hardware&#039;&#039;&#039;&#039;&#039; frei.&lt;br /&gt;
&lt;br /&gt;
[[Datei:fpu_1.png|FPU Abschalten Schritt 1]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;Compiler Settings -&amp;gt; Policy&#039;&#039;&#039;&#039;&#039; wählt man dann &#039;&#039;&#039;&#039;&#039;Use target options only&#039;&#039;&#039;&#039;&#039;. Dann kann man unter &#039;&#039;&#039;&#039;&#039;Categories&#039;&#039;&#039;&#039;&#039; die Option &#039;&#039;&#039;&#039;&#039;ARM FPU architecture&#039;&#039;&#039;&#039;&#039; auswählen. Dort stehen dann drei Möglichkeiten für die FPU zur Verfügung:&lt;br /&gt;
&lt;br /&gt;
1. Software-FPU-Library für Gleitkomma-Berechnung verwenden - Keine FPU-Instructions werden generiert (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=soft&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
2. Eine Mischung aus Software- und Hardware-FPU wird verwendet (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=softfp&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
3. Hardware-FPU wird für Gleitkomma-Berechnungen verwendet (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=hard&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
[[Datei:fpu_2.png|FPU Abschalten Schritt 2]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Um die FPU ab zu schalten wählt man natürlich die erste Möglichkeit.&lt;br /&gt;
Bei der 2. und 3. Möglichkeit fügt die IDE auch den Define &#039;&#039;&#039;&#039;&#039;__FPU_USED&#039;&#039;&#039;&#039;&#039; hinzu. Bei Der ersten Möglichkeit nicht. Der Code muss also nicht verändert / auskommentiert werden.&lt;br /&gt;
&lt;br /&gt;
Um die FPU wieder zu aktivieren müssen alle Schritte wieder rückgängig gemacht werden.&lt;br /&gt;
&lt;br /&gt;
Am besten ist es einfach mal alle Möglichkeiten im Einzelschritt durch zu probieren. Dann stellt man schnell fest, ob die FPU aktiviert wir oder nicht. Ein Blick in den erweiterten &#039;&#039;&#039;&#039;&#039;Build-Log&#039;&#039;&#039;&#039;&#039; gibt auch schnell Aufschluss darüber, wie der Compiler aufgerufen wird (siehe Kapitel [http://www.mikrocontroller.net/articles/STM32_-_Einstieg_mit_Em::Blocks#Compilieren Compilieren]).&lt;br /&gt;
&lt;br /&gt;
====Test Programm für die FPU====&lt;br /&gt;
Hier ein kleines Testprogramm, dass misst wie viele Taktzyklen für eine Gleitkomma-Multiplikation gebraucht werden. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define CORE_SysTickEn()    (*((u32*)0xE0001000)) = 0x40000001&lt;br /&gt;
#define CORE_SysTickDis()   (*((u32*)0xE0001000)) = 0x40000000&lt;br /&gt;
#define CORE_GetSysTick()   (*((u32*)0xE0001004))&lt;br /&gt;
&lt;br /&gt;
uint32_t t1, t2, dt;&lt;br /&gt;
float x, y, z;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    x = 53.64f;&lt;br /&gt;
    y = 0.27f;&lt;br /&gt;
&lt;br /&gt;
    CORE_SysTickEn();&lt;br /&gt;
    t1 = CORE_GetSysTick();&lt;br /&gt;
&lt;br /&gt;
    z = x * y;&lt;br /&gt;
&lt;br /&gt;
    t2 = CORE_GetSysTick();&lt;br /&gt;
    CORE_SysTickDis();&lt;br /&gt;
&lt;br /&gt;
    dt = (t2 - t1) - 9; //9 Takt-Zyklen werden für die Messung gebraucht &lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Booten aus dem SRAM==&lt;br /&gt;
STM32 Controller haben die Möglichkeit Code aus dem Flash als auch aus dem SRAM auszuführen. Um eine Anwenung per Debugger in des SRAM zu laden sind nur wenige Schritte erforderlich:&lt;br /&gt;
&lt;br /&gt;
*Um das Linkerscript für den SRAM zu verwenden geht man zu: &#039;&#039;&#039;&#039;&#039;Build options... -&amp;gt; Device&#039;&#039;&#039;&#039;&#039; dort wählt man unter &#039;&#039;&#039;&#039;&#039;Policy&#039;&#039;&#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;Use target settings&#039;&#039;&#039;&#039;&#039; aus und übernimmt die vorherigen Einstellungen, nur unter &#039;&#039;&#039;&#039;&#039;Linker script*&#039;&#039;&#039;&#039;&#039; gibt man &#039;&#039;&#039;&#039;&#039;.\stm32f407vg_sram.ld&#039;&#039;&#039;&#039;&#039; an&lt;br /&gt;
&lt;br /&gt;
*Dann muss man noch unter &#039;&#039;&#039;&#039;&#039;Debug -&amp;gt; Interfaces -&amp;gt; Settings&#039;&#039;&#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;Vector table start&#039;&#039;&#039;&#039;&#039; auf 0x20000000 ändern und &#039;&#039;&#039;&#039;&#039;Execute from RAM&#039;&#039;&#039;&#039;&#039; auswählen.&lt;br /&gt;
&lt;br /&gt;
Anschließend kann man die Anwendung ganz normal debuggen. Nach einem Reset muss die Anwenung erneut mit dem Debugger gestartet werden.&lt;br /&gt;
&lt;br /&gt;
=Fortsetzung folgt..=&lt;br /&gt;
Kritik, Wünsche usw. sind gerne erwünscht, am besten hier in den Thread posten: [http://www.mikrocontroller.net/topic/323750 Neues STM32 Tutorial]&lt;br /&gt;
&lt;br /&gt;
[[Category:ARM]]&lt;br /&gt;
[[Category:STM32]]&lt;/div&gt;</summary>
		<author><name>Avrprogger</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=STM32_-_Einstieg_mit_Em::Blocks&amp;diff=81545</id>
		<title>STM32 - Einstieg mit Em::Blocks</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=STM32_-_Einstieg_mit_Em::Blocks&amp;diff=81545"/>
		<updated>2014-02-11T16:42:49Z</updated>

		<summary type="html">&lt;p&gt;Avrprogger: cvb&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In diesem Tutorial werde ich versuchen, möglichst einfach, die ersten Schritte zur Entwicklung von STM32 Anwenungen mit der Em::Blocks IDE zu erklären. Hier soll nicht so stark auf die einzelnen Peripherie-Module der Controller eingegangen werden, sondern mehr auf die IDE und die verschieden Libraries, wie die CMSIS Library, die DSP-Library, die Standard-Peripheral-Library, die USB-Library und vllt. über Ethernet. Ich denke ein Kapitel zu FreeRTOS wird es auch geben. Auserdem steht im Vordergrund Sachen wie z.B. booten aus dem SRAM, In-Application-Programming, FPU, Core-Coupled-RAM usw. Mal sehn wie weit ich komme ;)&lt;br /&gt;
&lt;br /&gt;
==Die Entwicklungsumgebung==&lt;br /&gt;
===Hardware===&lt;br /&gt;
Zum testen der Anwendungen, benutze ich das STM32F4-Discovery Board, welches einen Debugger, Peripherie und natürlich einen STM32 Controller (STM32F407VGT6) enthält. Deshalb sind alle Beispiele hier für den STM32F407VG Controller ausgelegt, können aber meisten 1:1 auf andere Controller portiert werden. Ich werde auch möglichsts keine STM32F4-Discovery Board spezifischen Libraries verwenden, damit der Portierungs-Vorgang möglichsts einfach bleibt.&lt;br /&gt;
&lt;br /&gt;
===Software===&lt;br /&gt;
In diesem Tutorial verwende ich [http://www.emblocks.org/ Em::Blocks] als IDE. Em::Blocks ist eine kostenlose, uneingeschränkte IDE, die alle STM32 Mikrcontroller unterstützt und sehr einfach zu bedienen ist.&lt;br /&gt;
nach dem Download kann die IDE per Dialog, sehr einfach, installiert werden. Als Compiler beinhaltet Em::Blocks den &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
Die IDE unterstützt zurzeit den ST-Link, den J-Link und es gibt eine Generic-Vorlage, durch welche andere Debugger konfiguriert werden können.&lt;br /&gt;
&lt;br /&gt;
Außerdem muss noch der passende Treiber für den Debugger installiert werden. Verwendet man ein Discovery-Board muss der [http://www.st.com/web/catalog/tools/FM146/CL1984/SC724/SS1677/PF251168 ST-Link/V2]-Treiber heruntergeladen und installiert werden. (Die Installation muss evtl. als Administrator ausgeführt werden, da sonst die Installation unvollständig wird.) Nach der Installation des Treibers kann man den Debugger über die entsprechende USB Schnittstelle an den PC anschließen und es sollte die Meldung von Windows kommen, dass der richtige Treiber gefunden wurde.&lt;br /&gt;
&lt;br /&gt;
===Libraries===&lt;br /&gt;
Zum programmieren benötigt man noch die [http://www.arm.com/products/processors/cortex-m/cortex-microcontroller-software-interface-standard.php CMSIS] und die Standard-Peripheral-Library (z.B. für die F4 Controller [http://www.st.com/stonline/stappl/productcatalog/app?page=partNumberSearchPage&amp;amp;levelid=SS1577&amp;amp;parentid=1743&amp;amp;resourcetype=SW Standard-Peripheral-Library-F4]), die man am besten in einen Ordner (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\STM32&#039;&#039;&#039;&#039;&#039;) entpackt&lt;br /&gt;
&lt;br /&gt;
==Basis-Wissen zur IDE==&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von Dateien zum Projekt===&lt;br /&gt;
Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf &amp;lt;ProjektName&amp;gt; -&amp;gt; Add files...&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Enfernen von Dateien aus dem Projekt===&lt;br /&gt;
Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf die Datei / mehrere Dateien auswählen -&amp;gt; Remove file from project&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
Die Dateien werden lediglich aus dem Projekt entfernt und nicht von der Festplatte gelöscht.&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von Include-Pfaden===&lt;br /&gt;
Sofern die Include-Datei(en) nicht im standard Include-Ordner &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; des Projektes liegen, muss man den Pfad zum Projekt hinzufügen, damit der Compiler die Include-Dateien später auch finden kann. Man geht wie folgt vor: Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; Search Directories -&amp;gt; Add&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von globalen Defines zum Build===&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; #defines&#039;&#039;&#039;&#039;&#039; können globale Defines hinzugefügt werden.&lt;br /&gt;
&lt;br /&gt;
===Compilieren===&lt;br /&gt;
Entweder über das &#039;&#039;&#039;&#039;&#039;Build&#039;&#039;&#039;&#039;&#039; Menü oder über &#039;&#039;&#039;&#039;&#039;F7&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Um eine genau Ausgabe des Compiler-Aufrufes mit allen Argumenten zu bekommen, geht man im &#039;&#039;&#039;&#039;&#039;Settings&#039;&#039;&#039;&#039;&#039; Menü auf &#039;&#039;&#039;&#039;&#039;Tools...&#039;&#039;&#039;&#039;&#039; und dann auf &#039;&#039;&#039;&#039;&#039;Toolchain executables&#039;&#039;&#039;&#039;&#039;. Ganz unten, unter &#039;&#039;&#039;&#039;&#039;Logging&#039;&#039;&#039;&#039;&#039; kann man dann &#039;&#039;&#039;&#039;&#039;Full command line&#039;&#039;&#039;&#039;&#039; auswählen.&lt;br /&gt;
&lt;br /&gt;
====Compiler Optionen====&lt;br /&gt;
=====Optimierung=====&lt;br /&gt;
Standardmäßig verwendet Em::Blocks keine Optimierung. Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; Categories: Optimization&#039;&#039;&#039;&#039;&#039; kann zwischen verschieden Optimierungen ausgewählt werden.&lt;br /&gt;
&lt;br /&gt;
=====Verschiedene C-Standards=====&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; Categories: Language standard&#039;&#039;&#039;&#039;&#039; kann man zwischen verschieden C-Standard auswählen, wie z.B, C99.&lt;br /&gt;
(Mit C99 können auch die Lauf-Variable in der for-Schleife deklariert werden: for(int i;..))&lt;br /&gt;
&lt;br /&gt;
===Debuggen===&lt;br /&gt;
*Als erstes den Debugger starten über das &#039;&#039;&#039;&#039;&#039;Debug&#039;&#039;&#039;&#039;&#039; Menü und &#039;&#039;&#039;&#039;&#039;Start/stop Debug Session&#039;&#039;&#039;&#039;&#039; oder über &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
*Danach läuft die Anwendung auf dem Controller und warten im &#039;&#039;&#039;&#039;&#039;Reset_Handler&#039;&#039;&#039;&#039;&#039; auf Einzelschritt- bzw. Run- Befehle (&#039;&#039;&#039;&#039;&#039;F5, F10, F11&#039;&#039;&#039;&#039;&#039; usw..(siehe &#039;&#039;&#039;&#039;&#039;Debug-Menü&#039;&#039;&#039;&#039;&#039; für alle Möglichkeiten))&lt;br /&gt;
&lt;br /&gt;
*Mit &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039; wird die Debug-Session auch wieder beendet&lt;br /&gt;
&lt;br /&gt;
*Unter &#039;&#039;&#039;&#039;&#039;Debug -&amp;gt; Interfaces -&amp;gt; Target settings&#039;&#039;&#039;&#039;&#039; können Eigenschaften, wie z.B &#039;&#039;&#039;&#039;&#039;Run to main()&#039;&#039;&#039;&#039;&#039; aktiviert werden.&lt;br /&gt;
&lt;br /&gt;
===Projekt als Template abspeichern===&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;File -&amp;gt; Save project as template...&#039;&#039;&#039;&#039;&#039;. Das Template erscheint dann im Projekt-Dialog unter &#039;&#039;&#039;&#039;&#039;User templates&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Das erste Projekt erstellen==&lt;br /&gt;
Hier erkläre ich, wie man am Besten (aus meiner Sicht), ein neues Projekt von Grund auf erstellt, sodass man hinterher, den Controller-Kern über die CMSIS-Library und die Peripherie über die Register steuern kann.&lt;br /&gt;
&lt;br /&gt;
===1. Projekt mit der IDE erstellen===&lt;br /&gt;
Nach der Installation der oben beschriebenen Komponenten erstellt man am besten ein Verzeichnis (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\EmBlocks&#039;&#039;&#039;&#039;&#039;), indem später alle Projekte gespeichert werden. Für Libraries kann man auch noch ein Verzeichnis (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\STM32&#039;&#039;&#039;&#039;&#039;) erstellen, wo alle Libraries gespeichert werden, die man für die Projekt brauchen.&lt;br /&gt;
&lt;br /&gt;
Als nächstes starten man EmBlocks. Bei dem ersten Start öffnet sich ein Fenster, wo verschiedene Compiler angezeigt werden, die Em::Blocks findet. Dort wählt man den &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039; aus und klickt &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039;. Nun sollte sich das Hauptfenster von Em::Blocks öffnen. Über &#039;&#039;&#039;&#039;&#039;Create a new Project&#039;&#039;&#039;&#039;&#039; oder &#039;&#039;&#039;&#039;&#039;File -&amp;gt; New -&amp;gt; Project&#039;&#039;&#039;&#039;&#039; ruft man den Projekt-Dialog auf und kann ein neues Projekt erzeugen.&lt;br /&gt;
&lt;br /&gt;
Auf der Ersten Seite wählen man den &#039;&#039;&#039;&#039;&#039;STmicro-ARM&#039;&#039;&#039;&#039;&#039; Projekt-Typ aus.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_1.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auf der nächsten Seite wird man darauf hingewiesen, dass das der entsprechende Projekt-Typ-Dialog ausgeführt wird. Hier kann man ein Häkchen bei &#039;&#039;&#039;&#039;&#039;Skip this page next time&#039;&#039;&#039;&#039;&#039; setzen und auf &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; klicken.&lt;br /&gt;
&lt;br /&gt;
Im nächsten Schritt wählen man das zuvor erstellt Verzeichnis unter &#039;&#039;&#039;&#039;&#039;Folder to create Project in&#039;&#039;&#039;&#039;&#039; aus, indem später alle Projekt gespeichert werden. Außerdem geben wir dem Projekt einen Namen (z.B. &#039;&#039;&#039;&#039;&#039;FirstProject&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_2.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danach muss man einen Compiler auswählen und bestimmen, welche Projekt-Konfigurationen erszeugt werden sollen. Unter &#039;&#039;&#039;&#039;&#039;Compiler&#039;&#039;&#039;&#039;&#039; wählt man &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039; und man kann das Häkchen bei &#039;&#039;&#039;&#039;&#039;Create &amp;quot;Release&amp;quot; configuration&#039;&#039;&#039;&#039;&#039; entfernen, da diese unnötig ist, die Debug-Konfiguration sollte eig. immer ausreichen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_3.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auf den folgenden Seite wird der Controller ausgewählt. Verwendet man ein STM32F4-Discovery Board müssen folgende Dinge gewählt werden: &#039;&#039;&#039;&#039;&#039;Cortex_M4 (F3xx - F4xx) -&amp;gt; STM32F4xx (Cortex M4 with FPU) -&amp;gt; STM32F407VG&#039;&#039;&#039;&#039;&#039;. Leider sind die Auswahl Möglichkeiten nicht ganz richtig, da auch die F3 Controller einen Cortex M4 Kern und eine FPU haben (Ist aber nicht so wichtig, ist nur eine formale Sache). Außerdem entfernt man das Häkchen bei &#039;&#039;&#039;&#039;&#039;Standard Peripherals Library&#039;&#039;&#039;&#039;&#039; (Wie man die Standard-Peripheral-Library einbindet und verwendet erkläre ich später). Man kann auch das Häkchen bei &#039;&#039;&#039;&#039;&#039;Create hex file for Realease target&#039;&#039;&#039;&#039;&#039; entfernen.&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;Stack Size&#039;&#039;&#039;&#039;&#039; und &#039;&#039;&#039;&#039;&#039;Heap Size&#039;&#039;&#039;&#039;&#039; wird die Größe von Stack und Heap festgelegt. Für eine erste Anwendung kann man die Einstellungen so lassen (Stack-Size: 0x0100 =&amp;gt; 256 Byte Stack und Heap-Size: 0x0000 =&amp;gt; kein Heap). Mit &#039;&#039;&#039;&#039;&#039;Finish&#039;&#039;&#039;&#039;&#039; ist der Projekt Dialog abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_4.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danach sollten sich zwei neue Fenster öffnen, um die Debug-Eigenschaften fest zu legen.&lt;br /&gt;
Verwendet man ein Discovery Board/ST-Link müssen die Einstellungen wie auf dem Bild gewählt werden. Über den Button &#039;&#039;&#039;&#039;&#039;Settings&#039;&#039;&#039;&#039;&#039; öffnet sich das zweite Fenster, falls sich dieses nicht schon von alleine öffnen sollte. Nach den Schließen der Fenster über &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; ist der Projekt Dialog beendet und ein neues Projekt steht zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_5_1.png|Debug Eigenschaften 1. Fenster]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_5_2.png|Debug Eigenschaften 2. Fenster]]&lt;br /&gt;
&lt;br /&gt;
===2. CMSIS-Library und Startup-Code hinzufügen===&lt;br /&gt;
Wenn man sich, nachdem man ein neues Projekt in der IDE erstellt hat, die bereits vorhandenen Dateien im Projekt ansieht, stellt man fest, das bereits ein Ordner &#039;&#039;&#039;&#039;&#039;cmsis&#039;&#039;&#039;&#039;&#039; existiert, der einige wichtige Include-Dateien der CMSIS-Library enthält. Allerdings sind das wirklich nur die wichtigsten Include-Dateien der CMSIS-Library und dazu noch, die aus einer älternen Version. Ich ziehe es deshalb vor die &amp;quot;Mini-CMSIS-Libraray&amp;quot; und die &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c/.h&#039;&#039;&#039;&#039;&#039; Dateien des Projektes durch aktuellere Versionen zu ersetzen. So ist später auch die Integration  von anderen Libraries, wie z.B. der CMSIS-DSP-Libarary einfacher.  &lt;br /&gt;
&lt;br /&gt;
Zunächst gehen man in das Projekt-Verzeichnis und löscht:&lt;br /&gt;
*Den Ordner &#039;&#039;&#039;&#039;&#039;cmsis&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Alle Dateien im Include Verzeichnis &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; im &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner&lt;br /&gt;
&lt;br /&gt;
Außerdem entfernt man auch alle gelöschten Dateien in der IDE aus dem Projekt mit &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Rechts Klick -&amp;gt; Remove file from project&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Es sollte folgende Verzeichnis Struktur überbleiben:&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_6.png|Überbleibende Dateien]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Jetzt müssen die gelöschten Dateien durch die aktuelleren ersetzt werden.&lt;br /&gt;
&lt;br /&gt;
*Dazu kopieren man den gesamten Ordner &#039;&#039;&#039;&#039;&#039;CMSIS&#039;&#039;&#039;&#039;&#039; aus dem CMSIS Download in das Projekt Verzeichnis.&lt;br /&gt;
&lt;br /&gt;
*Aus dem Standard-Peripheral-Library Download kopiert man von &#039;&#039;&#039;&#039;&#039;Libraries\CMSIS\Device\ST\STM32F4xx\Include&#039;&#039;&#039;&#039;&#039; alle Dateien in den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projekt Verzeichnisses&lt;br /&gt;
&lt;br /&gt;
*Aus der Standard-Peripheral-Library kopieren man ebenfalls von &#039;&#039;&#039;&#039;&#039;Libraries\CMSIS\Device\ST\STM32F4xx\Source\Templates&#039;&#039;&#039;&#039;&#039; die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; in den &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner des Projekts&lt;br /&gt;
&lt;br /&gt;
Anschließend müssen die neuen Dateien in der IDE dem Projekt hinzugefügt werden. Dazu benutzt man &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Rechts Klick -&amp;gt; Add files&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
*Aus dem &#039;&#039;&#039;&#039;&#039;CMSIS&#039;&#039;&#039;&#039;&#039; Ordner im Projekt Verzeichnis werden aus den Unterorder &#039;&#039;&#039;&#039;&#039;Include&#039;&#039;&#039;&#039;&#039; folgende Dateien dem Projekt hinzugefügt:&lt;br /&gt;
**arm_common_tables.h&lt;br /&gt;
**arm_const_structs.h&lt;br /&gt;
**arm_math.h&lt;br /&gt;
**core_cm4.h&lt;br /&gt;
**core_cm4_simd.h&lt;br /&gt;
**core_cmFunc.h&lt;br /&gt;
**core_cmInstr.h&lt;br /&gt;
*Alle Dateien aus den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projektes&lt;br /&gt;
*Die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; aus dem &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner&lt;br /&gt;
&lt;br /&gt;
So sollte die Struktur dann aussehen:&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_7.png|Anwenungs-Grundgerüst]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Da einige Dateien der Libraries später bearbeitet werden müssen und Schreibgeschützt sind, weise ich hier schonmal darauf hin, das der Schreibschutz in der IDE über &#039;&#039;&#039;&#039;&#039;Rechts Klick auf die Datei -&amp;gt; Properties -&amp;gt; Häkchen bei &amp;quot;File is read only&amp;quot; entfernen&#039;&#039;&#039;&#039;&#039; entfert werden kann.&lt;br /&gt;
&lt;br /&gt;
Damit die IDE die Header-Dateien der CMSIS Library auch finden kann, weil diese ja nicht im standard Include Ordner &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; liegen, muss unter &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Build Options -&amp;gt; Search Directories&#039;&#039;&#039;&#039;&#039; der Pfad &#039;&#039;&#039;&#039;&#039;CMSIS\Include&#039;&#039;&#039;&#039;&#039; hinzugefügt werden.&lt;br /&gt;
&lt;br /&gt;
Compiliert man jetzt das Projekt mit &#039;&#039;&#039;&#039;&#039;F7&#039;&#039;&#039;&#039;&#039; gibt es ein paar Fehler Meldungen, weil keine Controller-Reihe ausgewählt wurde. Ebenfalls unter &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Build Options -&amp;gt; Compiler Settings -&amp;gt; #defines&#039;&#039;&#039;&#039;&#039; wird der Define &#039;&#039;&#039;&#039;&#039;STM32F40_41xxx&#039;&#039;&#039;&#039;&#039; hinzugefügt.&lt;br /&gt;
&lt;br /&gt;
Beim erneuten Compilieren sollten sich nun keine neuen Fehler ergeben.&lt;br /&gt;
&lt;br /&gt;
===3. Das erste Programm===&lt;br /&gt;
Nachdem ein grundsätzliches &amp;quot;Gerüst&amp;quot; fertig ist, kann man den ersten Code schreiben.&lt;br /&gt;
main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC-&amp;gt;AHB1ENR |= RCC_AHB1ENR_GPIODEN;    //Takt für GPIO aktivieren&lt;br /&gt;
    GPIOD-&amp;gt;MODER |= GPIO_MODER_MODER15_0;   //GPIOD Pin15 als Ausgang&lt;br /&gt;
    GPIOD-&amp;gt;BSRRL |= GPIO_BSRR_BS_15;        //GPIOD Pin15 auf High ziehen&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039; wird dann der Debugger gestartet. Hat der Debugger das Projekt erfolgreich übertragen kann die Ausführung mit &#039;&#039;&#039;&#039;&#039;F5&#039;&#039;&#039;&#039;&#039; begonnen werden.&lt;br /&gt;
&lt;br /&gt;
==Libraries einbinden/verwenden==&lt;br /&gt;
===Einbinden der Standard-Peripheral-Library===&lt;br /&gt;
Um nicht immer die einzelnen Register, wie im ersten &amp;quot;bare-metal&amp;quot; Beispiel, aus dem Reference-Manual zu suchen und zu beschreiben, gibt es von ST die Standard Peripheral Library, die diese Aufgaben übernimmt und mit der sich die &amp;quot;normale/grundlegende&amp;quot; (Alles außer USB und Ethernet) Peripherie recht einfach steuern lässt. Um die Library zu verwenden erzeugt man wie oben beschrieben ein neues Grundgerüst und kopiert als erstes den Ordner &#039;&#039;&#039;&#039;&#039;Libraries\STM32F4xx_StdPeriph_Driver&#039;&#039;&#039;&#039;&#039; aus dem Standard-Peripheral-Library Download in das Projekt-Verzeichnis. Außerdem muss man die Datei &#039;&#039;&#039;&#039;&#039;Project\STM32F4xx_StdPeriph_Templates\stm32f4xx_conf.h&#039;&#039;&#039;&#039;&#039; ebenfalls aus dem Standard-Peripheral-Library Download in den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projektes kopieren. In der IDE fügt man den Include-Path &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\inc&#039;&#039;&#039;&#039;&#039; hinzufügen, wie bei der CMSIS-Library (s.o.).&lt;br /&gt;
Außerdem muss noch &#039;&#039;&#039;&#039;&#039;USE_STDPERIPH_DRIVER&#039;&#039;&#039;&#039;&#039; als Define in der IDE hinzugefügt werden (s.o.).&lt;br /&gt;
Danach fügt man die Source- und Include-Dateien aus dem Ordner &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\inc&#039;&#039;&#039;&#039;&#039; und &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\src&#039;&#039;&#039;&#039;&#039; dem Project mit &#039;&#039;&#039;&#039;&#039;&amp;lt;Project Name&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Add files&#039;&#039;&#039;&#039;&#039; hinzu, allerdings nur die, für welche auch der Controller die entsprechende Peripherie besitzt. Beim STM32F4-Discovery Board / STM32F407VG Controller dürfen also nicht folgende Dateien nicht mit hinzugefügt werden, weil diese Peripherie nur bei anderen Controller vorhanden ist:&lt;br /&gt;
&lt;br /&gt;
*stm32f4xx_dma2d.c/.h&lt;br /&gt;
*stm32f4xx_fmc.c/.h&lt;br /&gt;
*stm32f4xx_ltdc.c/.h&lt;br /&gt;
*stm32f4xx_sai.c/.h&lt;br /&gt;
&lt;br /&gt;
Daraus resultiert folgende Struktur:&lt;br /&gt;
&lt;br /&gt;
[[Datei:stdperiphlib_2.png|Header-Struktur]] [[Datei:stdperiphlib_1.png|Source-Struktur]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Anschließen kann die Standard-Peripheral-Library benutz werden.&lt;br /&gt;
main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);&lt;br /&gt;
&lt;br /&gt;
    GPIO_InitTypeDef GPIOD_InitStructure;&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Mode = GPIO_Mode_OUT;     //Als Ausgang&lt;br /&gt;
    GPIOD_InitStructure.GPIO_OType = GPIO_OType_PP;    //Push-Pull Betrieb&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Pin = GPIO_Pin_15;        //Pin 15 (STM32F4-Discovery: Blaue LED)&lt;br /&gt;
    GPIOD_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;  //Kein Pull-Up oder Pull-Down Widerstand aktiviert&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Speed = GPIO_Speed_25MHz; //25MHz Update-Rate&lt;br /&gt;
    GPIO_Init(GPIOD, &amp;amp;GPIOD_InitStructure);&lt;br /&gt;
&lt;br /&gt;
    GPIO_SetBits(GPIOD, GPIO_Pin_15);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Einbinden der DSP-Library===&lt;br /&gt;
STM32F3 / STM32F4 Microcontroller haben neben der FPU noch einen Digital-Signal-Processor (DSP). Die DSP dient hauptsächlich dazu, viele Daten schnell zu verarbeiten (z.B. Video- oder Audiosignal). Der CMSIS-Download beinhaltet dazu neben der eigentlichen CMSIS-Library auch noch eine DSP-Library. Diese Library stellt sowohl einfache, mathematische Funktionen wie addieren, multiplizieren usw. als auch komplexe Funktionen, wie z.B  einen IIR-Filter, zur Verfügung. Die DSP-Library ist weiter aufgeteilt in kleinere Module, wie z.B. BasicMathFunctions, FilteringFunctions usw. (siehe &#039;&#039;&#039;&#039;&#039;CMSIS\DSP-Library\Source&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
Um die DSP-Library zu verwenden müssen nur die Source-Files des benötigten Moduls einbinden.&lt;br /&gt;
(&#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Add files...&#039;&#039;&#039;&#039;&#039;). Außerdem muss in der &#039;&#039;&#039;&#039;&#039;main.c&#039;&#039;&#039;&#039;&#039; der Include &#039;&#039;&#039;&#039;&#039;arm_math.h&#039;&#039;&#039;&#039;&#039; eingebunden werden. Aus irgendeinem Grund gibt es dann jedoch die Warnung: &amp;quot;Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)&amp;quot;. Ich hab noch nicht rausgefunden, wieso diese Warnung auftaucht. Die Warnung verschwindet, wenn man in der &#039;&#039;&#039;&#039;&#039;Build options...&#039;&#039;&#039;&#039;&#039; das Define &#039;&#039;&#039;&#039;&#039;__FPU_PRESENT&#039;&#039;&#039;&#039;&#039; hinzufügt (Ich weiß selber das das keine schöne Lösung ist, eine andere hab ich jedoch noch nicht gefunden). Jetzt kann die DSP-Library verwedet werden. Das Beispiel multipliziert zwei Buffer miteinander. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
#include &amp;quot;arm_math.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    float32_t x[1024];&lt;br /&gt;
    float32_t y[1024];&lt;br /&gt;
    float32_t z[1024];&lt;br /&gt;
&lt;br /&gt;
    for(uint16_t i = 0; i &amp;lt; 1024; i++)&lt;br /&gt;
    {&lt;br /&gt;
        x[i] = i;&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for(uint16_t i = 0; i &amp;lt; 1024; i++)&lt;br /&gt;
    {&lt;br /&gt;
        y[i] = PI;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    arm_mult_f32(x, y, z, 1024);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Startup-Code, Linker-Script, Takt, FPU usw.==&lt;br /&gt;
===Startup-Code===&lt;br /&gt;
Em::Blocks fügt standardmäßig einen Startup-Code mit in das Projekt ein. Die wichtigsten Dinge die darin erledigt werden sind folgende:&lt;br /&gt;
&lt;br /&gt;
*Stack und Heap wird angelgt&lt;br /&gt;
*Die Vector-Table wird angelegt&lt;br /&gt;
*Ein Default Reset-Handler wird implementiert, dieser erledigt folgende aufgaben:&lt;br /&gt;
**Kopieren der definierten Daten aus dem Flash in den SRAM&lt;br /&gt;
**&#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; wird aufgerfen, wenn &#039;&#039;&#039;&#039;&#039;__NO_SYSTEM_INIT&#039;&#039;&#039;&#039;&#039; nicht definiert ist&lt;br /&gt;
**Sprung in die &#039;&#039;&#039;&#039;&#039;main()&#039;&#039;&#039;&#039;&#039; Funktion&lt;br /&gt;
*Allen anderen Interrupt-Handler wird eine Default-Funktion &#039;&#039;&#039;&#039;&#039;def_irq_handler&#039;&#039;&#039;&#039;&#039; mit einer &#039;&#039;&#039;&#039;&#039;while(1)&#039;&#039;&#039;&#039;&#039;-Schleife zugewiesen, falls kein anderer Interrupt-Handler existiert.&lt;br /&gt;
&lt;br /&gt;
Normalerweise muss am Startup-Code nichts verändert werden.&lt;br /&gt;
&lt;br /&gt;
===Linker-Script===&lt;br /&gt;
Em::Blocks stellt zwei fertige Linker-Scripts bereit, eins für die Ausführung des Programmes aus dem Flash (&#039;&#039;&#039;&#039;&#039;*_flash.ld&#039;&#039;&#039;&#039;&#039;), das andere für die Ausführung aus dem SRAM (&#039;&#039;&#039;&#039;&#039;*_sram.ld&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Normalerweise muss auch hier nichts geändert werden, es sei den Daten sollen in bestimmten Adressbereichen abgelegt werden (z.B. im Core-Coupled RAM), was ich später noch zum Tutorial hinzufüge.&lt;br /&gt;
&lt;br /&gt;
===Der Takt===&lt;br /&gt;
Jeder Controller oder Prozessor braucht einen Takt, indem er die einzelnen Maschinen-Befehle abarbeiten kann.&lt;br /&gt;
Bei den STM32 Mikrocontrollern kann dieser Takt aus verschiedenen Quellen kommen:&lt;br /&gt;
&lt;br /&gt;
1. High Speed Internal Oszillator (HSI)&lt;br /&gt;
&lt;br /&gt;
2. High Speed External Oszillator (HSE)&lt;br /&gt;
&lt;br /&gt;
3. Low Speed Internal Oszillator (LSI)&lt;br /&gt;
&lt;br /&gt;
4. Low Speed External Oszillator (LSE)&lt;br /&gt;
&lt;br /&gt;
5. Phase-Locked Loop (PLL) (generiert den Takt aus den ersten vier Taktquellen durch Teiler und Faktoren)&lt;br /&gt;
&lt;br /&gt;
Nach einem Reset wird der Controller aus der HSI Taktquelle versorgt (16MHz beim STM32F407VG). Um die voll Performance des Controllers zu erreichen muss die PLL verwendet werden, welche den Takt durch geschickte Teiler und Faktoren vervielfältigt, sodass am Ende der Controller mit der maximalen Taktfrequenz läuft. Die notwendige Initialisierung der PLL findet in der Funktion &#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; statt. Die PLL erzeugt zunächst einen Basistakt:&lt;br /&gt;
&lt;br /&gt;
PLL_VCO = (F_HSE / PLL_M) * PLL_N&lt;br /&gt;
&lt;br /&gt;
Aus diesem Takt wird dann der Takt für den Controller-Kern abgeleitet:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = PLL_VCO / PLL_P&lt;br /&gt;
&lt;br /&gt;
Und der Takt für SDIO / USB / RNG (48MHz):&lt;br /&gt;
&lt;br /&gt;
48MHz = PLL_VCO / PLL_Q&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Durch weiter Teiler werden, die Takte für die einzelnen Busse erzeugt, da diese nicht alle beliebig schnell betrieben werden dürfen.&lt;br /&gt;
&lt;br /&gt;
Genaue Angaben findet man zu dem jeweiligen Clock-System des Controllers im Reference Manual.&lt;br /&gt;
&lt;br /&gt;
Ein Blick in den &amp;quot;Kommentar-Header&amp;quot; verrät, dass von einem externen (HSE) Oszillator von 25MHz ausgegangen wird, der die PLL versorgen soll.&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((25MHz / PLL_M(25)) * PLL_N(336)) / PLL_P(2) = 168MHz&lt;br /&gt;
&lt;br /&gt;
Allerdings stimmt diese Rechnung natürlich nur, wenn wirklich ein 25MHz Quarz am Controller angeschlossen ist. Auf dem STM32F4-Discovery Board befindet sich aber nur ein 8MHz Quarz. Demnach gilt:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((8MHz / PLL_M(25)) * PLL_N(336)) / PLL_P(2) = 53.76MHz&lt;br /&gt;
&lt;br /&gt;
Der Controller läuft also nur mit 53.76MHz, wenn wie ober beschrieben ein Projekt erstellt wird. Allerdings kann dieses Problem durch ändern von den betroffen Defines behoben werden:&lt;br /&gt;
 &lt;br /&gt;
*Dazu geht man in die &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; Datei und passt zur Vollständigkeit erstmal die zum Controller passende Tabelle im &amp;quot;Kommentar-Header&amp;quot; an (Z.57f):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      HSE Frequency(Hz)                      | 8000000&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      PLL_M                                  | 8&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Danach passt man den PPL_M Define (Z.254) an:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/************************* PLL Parameters *************************************/&lt;br /&gt;
/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */&lt;br /&gt;
#define PLL_M      8&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Außerdem muss man den HSE_VALUE Define in der &#039;&#039;&#039;&#039;&#039;inc/stm32f4xx.h&#039;&#039;&#039;&#039;&#039; angepasst werden (Z.122):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#if !defined  (HSE_VALUE)&lt;br /&gt;
  #define HSE_VALUE    ((uint32_t)8000000) /*!&amp;lt; Value of the External oscillator in Hz */&lt;br /&gt;
&lt;br /&gt;
#endif /* HSE_VALUE */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine neue Berechnung zeigt:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((8MHz / PLL_M(8)) * PLL_N(336)) / PLL_P(2) = 168MHz&lt;br /&gt;
&lt;br /&gt;
Jetzt läuft der Controller mit maximaler Geschwindigkeit.&lt;br /&gt;
&lt;br /&gt;
Die Theorie wird durch folgendes Programm verifiziert. Der geviertelte System-Takt SYSCLK wir am Pin PC9 ausgegeben. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);&lt;br /&gt;
&lt;br /&gt;
    GPIO_InitTypeDef GPIOC_InitStructure;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Mode = GPIO_Mode_AF;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_OType = GPIO_OType_PP;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Pin = GPIO_Pin_9;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;&lt;br /&gt;
    GPIO_Init(GPIOC, &amp;amp;GPIOC_InitStructure);&lt;br /&gt;
&lt;br /&gt;
    RCC_MCO2Config(RCC_MCO2Source_SYSCLK, RCC_MCO2Div_4);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Die FPU===&lt;br /&gt;
====Allgemeines====&lt;br /&gt;
STM32F3 und STM32F4 Controller haben eine FPU.&lt;br /&gt;
Damit die FPU richtig verwendet wird, müssen normalerweise zwei Bedingungen erfüllt sein:&lt;br /&gt;
&lt;br /&gt;
1. Der Controller muss die FPU Hardware-seitig aktivieren&lt;br /&gt;
&lt;br /&gt;
2. Damit die FPU auch was zu tuen bekommt, müssen vom Compiler FPU-Instructions erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
Die Em::Blocks IDE verwendet standardmäßig die FPU, wenn eine Vorhanden ist. Hier wird die FPU Hardware-seitig aktiviert (&#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; Z.341):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* FPU settings ------------------------------------------------------------*/&lt;br /&gt;
  #if (__FPU_PRESENT == 1) &amp;amp;&amp;amp; (__FPU_USED == 1)&lt;br /&gt;
    SCB-&amp;gt;CPACR |= ((3UL &amp;lt;&amp;lt; 10*2)|(3UL &amp;lt;&amp;lt; 11*2));  /* set CP10 and CP11 Full Access */&lt;br /&gt;
  #endif&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
__FPU_PRESENT wird in der &#039;&#039;&#039;&#039;&#039;stm32f4xx.h&#039;&#039;&#039;&#039;&#039; definiert.&lt;br /&gt;
__FPU_USED wird von der IDE übernommen (siehe Build-Log): &#039;&#039;&#039;&#039;&#039;-D__FPU_USED&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Außerdem wird der Compiler von der IDE standardmäßig mit dem Argument &#039;&#039;&#039;&#039;&#039;-mfloat-abi=hard&#039;&#039;&#039;&#039;&#039; aufgerufen, wodurch FPU-Instructions erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
====FPU abschalten====&lt;br /&gt;
Um die FPU ab zu schalten (Mir würde jetzt nur Strom sparen als Grund einfallen) geht man wie folgt vor:&lt;br /&gt;
&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick Build options -&amp;gt; Device -&amp;gt; Policy&#039;&#039;&#039;&#039;&#039; wählt man &#039;&#039;&#039;&#039;&#039;Use target settings&#039;&#039;&#039;&#039;&#039; und über nimmt die Einstellungen, die vorher dort eingetragen waren, allerdings lässt man das Feld &#039;&#039;&#039;&#039;&#039;FP-hardware&#039;&#039;&#039;&#039;&#039; frei.&lt;br /&gt;
&lt;br /&gt;
[[Datei:fpu_1.png|FPU Abschalten Schritt 1]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;Compiler Settings -&amp;gt; Policy&#039;&#039;&#039;&#039;&#039; wählt man dann &#039;&#039;&#039;&#039;&#039;Use target options only&#039;&#039;&#039;&#039;&#039;. Dann kann man unter &#039;&#039;&#039;&#039;&#039;Categories&#039;&#039;&#039;&#039;&#039; die Option &#039;&#039;&#039;&#039;&#039;ARM FPU architecture&#039;&#039;&#039;&#039;&#039; auswählen. Dort stehen dann drei Möglichkeiten für die FPU zur Verfügung:&lt;br /&gt;
&lt;br /&gt;
1. Software-FPU-Library für Gleitkomma-Berechnung verwenden - Keine FPU-Instructions werden generiert (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=soft&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
2. Eine Mischung aus Software- und Hardware-FPU wird verwendet (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=softfp&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
3. Hardware-FPU wird für Gleitkomma-Berechnungen verwendet (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=hard&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
[[Datei:fpu_2.png|FPU Abschalten Schritt 2]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Um die FPU ab zu schalten wählt man natürlich die erste Möglichkeit.&lt;br /&gt;
Bei der 2. und 3. Möglichkeit fügt die IDE auch den Define &#039;&#039;&#039;&#039;&#039;__FPU_USED&#039;&#039;&#039;&#039;&#039; hinzu. Bei Der ersten Möglichkeit nicht. Der Code muss also nicht verändert / auskommentiert werden.&lt;br /&gt;
&lt;br /&gt;
Um die FPU wieder zu aktivieren müssen alle Schritte wieder rückgängig gemacht werden.&lt;br /&gt;
&lt;br /&gt;
Am besten ist es einfach mal alle Möglichkeiten im Einzelschritt durch zu probieren. Dann stellt man schnell fest, ob die FPU aktiviert wir oder nicht. Ein Blick in den erweiterten &#039;&#039;&#039;&#039;&#039;Build-Log&#039;&#039;&#039;&#039;&#039; gibt auch schnell Aufschluss darüber, wie der Compiler aufgerufen wird (siehe Kapitel [http://www.mikrocontroller.net/articles/STM32_-_Einstieg_mit_Em::Blocks#Compilieren Compilieren]).&lt;br /&gt;
&lt;br /&gt;
====Test Programm für die FPU====&lt;br /&gt;
Hier ein kleines Testprogramm, dass misst wie viele Taktzyklen für eine Gleitkomma-Multiplikation gebraucht werden. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define CORE_SysTickEn()    (*((u32*)0xE0001000)) = 0x40000001&lt;br /&gt;
#define CORE_SysTickDis()   (*((u32*)0xE0001000)) = 0x40000000&lt;br /&gt;
#define CORE_GetSysTick()   (*((u32*)0xE0001004))&lt;br /&gt;
&lt;br /&gt;
uint32_t t1, t2, dt;&lt;br /&gt;
float x, y, z;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    x = 53.64f;&lt;br /&gt;
    y = 0.27f;&lt;br /&gt;
&lt;br /&gt;
    CORE_SysTickEn();&lt;br /&gt;
    t1 = CORE_GetSysTick();&lt;br /&gt;
&lt;br /&gt;
    z = x * y;&lt;br /&gt;
&lt;br /&gt;
    t2 = CORE_GetSysTick();&lt;br /&gt;
    CORE_SysTickDis();&lt;br /&gt;
&lt;br /&gt;
    dt = (t2 - t1) - 9; //9 Takt-Zyklen werden für die Messung gebraucht &lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Booten aus dem SRAM==&lt;br /&gt;
STM32 Controller haben die Möglichkeit Code aus dem Flash als auch aus dem SRAM auszuführen. Um eine Anwenung per Debugger in des SRAM zu laden sind nur wenige Schritte erforderlich:&lt;br /&gt;
&lt;br /&gt;
*Um das Linkerscript für den SRAM zu verwenden geht man zu: &#039;&#039;&#039;&#039;&#039;Build options... -&amp;gt; Device&#039;&#039;&#039;&#039;&#039; dort wählt man unter &#039;&#039;&#039;&#039;&#039;Policy&#039;&#039;&#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;Use target settings&#039;&#039;&#039;&#039;&#039; aus und übernimmt die vorherigen Einstellungen, nur unter &#039;&#039;&#039;&#039;&#039;Linker script*&#039;&#039;&#039;&#039;&#039; gibt man &#039;&#039;&#039;&#039;&#039;.\stm32f407vg_sram.ld&#039;&#039;&#039;&#039;&#039; an&lt;br /&gt;
&lt;br /&gt;
*Dann muss man noch unter &#039;&#039;&#039;&#039;&#039;Debug -&amp;gt; Interfaces -&amp;gt; Settings&#039;&#039;&#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;Vector table start&#039;&#039;&#039;&#039;&#039; auf 0x20000000 ändern und &#039;&#039;&#039;&#039;&#039;Execute from RAM&#039;&#039;&#039;&#039;&#039; auswählen.&lt;br /&gt;
&lt;br /&gt;
Anschließend kann man die Anwendung ganz normal debuggen. Nach einem Reset muss die Anwenung erneut mit dem Debugger gestartet werden.&lt;br /&gt;
&lt;br /&gt;
=Fortsetzung folgt..=&lt;br /&gt;
Kritik, Wünsche usw. sind gerne erwünscht, am besten hier in den Thread posten: [http://www.mikrocontroller.net/topic/323750 Neues STM32 Tutorial]&lt;br /&gt;
&lt;br /&gt;
[[Category:ARM]]&lt;br /&gt;
[[Category:STM32]]&lt;/div&gt;</summary>
		<author><name>Avrprogger</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=STM32_-_Einstieg_mit_Em::Blocks&amp;diff=81544</id>
		<title>STM32 - Einstieg mit Em::Blocks</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=STM32_-_Einstieg_mit_Em::Blocks&amp;diff=81544"/>
		<updated>2014-02-11T16:41:20Z</updated>

		<summary type="html">&lt;p&gt;Avrprogger: xcv&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In diesem Tutorial werde ich versuchen, möglichst einfach, die ersten Schritte zur Entwicklung von STM32 Anwenungen mit der Em::Blocks IDE zu erklären. Hier soll nicht so stark auf die einzelnen Peripherie-Module der Controller eingegangen werden, sondern mehr auf die IDE und die verschieden Libraries, wie die CMSIS Library, die DSP-Library, die Standard-Peripheral-Library, die USB-Library und vllt. über Ethernet. Ich denke ein Kapitel zu FreeRTOS wird es auch geben. Auserdem steht im Vordergrund Sachen wie z.B. booten aus dem SRAM, In-Application-Programming, FPU, Core-Coupled-RAM usw. Mal sehn wie weit ich komme ;)&lt;br /&gt;
&lt;br /&gt;
==Die Entwicklungsumgebung==&lt;br /&gt;
===Hardware===&lt;br /&gt;
Zum testen der Anwendungen, benutze ich das STM32F4-Discovery Board, welches einen Debugger, Peripherie und natürlich einen STM32 Controller (STM32F407VGT6) enthält. Deshalb sind alle Beispiele hier für den STM32F407VG Controller ausgelegt, können aber meisten 1:1 auf andere Controller portiert werden. Ich werde auch möglichsts keine STM32F4-Discovery Board spezifischen Libraries verwenden, damit der Portierungs-Vorgang möglichsts einfach bleibt.&lt;br /&gt;
&lt;br /&gt;
===Software===&lt;br /&gt;
In diesem Tutorial verwende ich [http://www.emblocks.org/ Em::Blocks] als IDE. Em::Blocks ist eine kostenlose, uneingeschränkte IDE, die alle STM32 Mikrcontroller unterstützt und sehr einfach zu bedienen ist.&lt;br /&gt;
nach dem Download kann die IDE per Dialog, sehr einfach, installiert werden. Als Compiler beinhaltet Em::Blocks den &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
Die IDE unterstützt zurzeit den ST-Link, den J-Link und es gibt eine Generic-Vorlage, durch welche andere Debugger konfiguriert werden können.&lt;br /&gt;
&lt;br /&gt;
Außerdem muss noch der passende Treiber für den Debugger installiert werden. Verwendet man ein Discovery-Board muss der [http://www.st.com/web/catalog/tools/FM146/CL1984/SC724/SS1677/PF251168 ST-Link/V2]-Treiber heruntergeladen und installiert werden. (Die Installation muss evtl. als Administrator ausgeführt werden, da sonst die Installation unvollständig wird.) Nach der Installation des Treibers kann man den Debugger über die entsprechende USB Schnittstelle an den PC anschließen und es sollte die Meldung von Windows kommen, dass der richtige Treiber gefunden wurde.&lt;br /&gt;
&lt;br /&gt;
===Libraries===&lt;br /&gt;
Zum programmieren benötigt man noch die [http://www.arm.com/products/processors/cortex-m/cortex-microcontroller-software-interface-standard.php CMSIS] und die Standard-Peripheral-Library (z.B. für die F4 Controller [http://www.st.com/stonline/stappl/productcatalog/app?page=partNumberSearchPage&amp;amp;levelid=SS1577&amp;amp;parentid=1743&amp;amp;resourcetype=SW Standard-Peripheral-Library-F4]), die man am besten in einen Ordner (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\STM32&#039;&#039;&#039;&#039;&#039;) entpackt&lt;br /&gt;
&lt;br /&gt;
==Basis-Wissen zur IDE==&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von Dateien zum Projekt===&lt;br /&gt;
Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf &amp;lt;ProjektName&amp;gt; -&amp;gt; Add files...&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Enfernen von Dateien aus dem Projekt===&lt;br /&gt;
Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf die Datei / mehrere Dateien auswählen -&amp;gt; Remove file from project&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
Die Dateien werden lediglich aus dem Projekt entfernt und nicht von der Festplatte gelöscht.&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von Include-Pfaden===&lt;br /&gt;
Sofern die Include-Datei(en) nicht im standard Include-Ordner &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; des Projektes liegen, muss man den Pfad zum Projekt hinzufügen, damit der Compiler die Include-Dateien später auch finden kann. Man geht wie folgt vor: Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; Search Directories -&amp;gt; Add&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von globalen Defines zum Build===&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; #defines&#039;&#039;&#039;&#039;&#039; können globale Defines hinzugefügt werden.&lt;br /&gt;
&lt;br /&gt;
===Compilieren===&lt;br /&gt;
Entweder über das &#039;&#039;&#039;&#039;&#039;Build&#039;&#039;&#039;&#039;&#039; Menü oder über &#039;&#039;&#039;&#039;&#039;F7&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Um eine genau Ausgabe des Compiler-Aufrufes mit allen Argumenten zu bekommen, geht man im &#039;&#039;&#039;&#039;&#039;Settings&#039;&#039;&#039;&#039;&#039; Menü auf &#039;&#039;&#039;&#039;&#039;Tools...&#039;&#039;&#039;&#039;&#039; und dann auf &#039;&#039;&#039;&#039;&#039;Toolchain executables&#039;&#039;&#039;&#039;&#039;. Ganz unten, unter &#039;&#039;&#039;&#039;&#039;Logging&#039;&#039;&#039;&#039;&#039; kann man dann &#039;&#039;&#039;&#039;&#039;Full command line&#039;&#039;&#039;&#039;&#039; auswählen.&lt;br /&gt;
&lt;br /&gt;
====Compiler Optionen====&lt;br /&gt;
=====Optimierung=====&lt;br /&gt;
Standardmäßig verwendet Em::Blocks keine Optimierung. Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; Categories: Optimization&#039;&#039;&#039;&#039;&#039; kann zwischen verschieden Optimierungen ausgewählt werden.&lt;br /&gt;
&lt;br /&gt;
=====Verschiedene C-Standards=====&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; Categories: Language standard&#039;&#039;&#039;&#039;&#039; kann man zwischen verschieden C-Standard auswählen, wie z.B, C99.&lt;br /&gt;
(Mit C99 können auch die Lauf-Variable in der for-Schleife deklariert werden: for(int i;..))&lt;br /&gt;
&lt;br /&gt;
===Debuggen===&lt;br /&gt;
*Als erstes den Debugger starten über das &#039;&#039;&#039;&#039;&#039;Debug&#039;&#039;&#039;&#039;&#039; Menü und &#039;&#039;&#039;&#039;&#039;Start/stop Debug Session&#039;&#039;&#039;&#039;&#039; oder über &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
*Danach läuft die Anwendung auf dem Controller und warten im &#039;&#039;&#039;&#039;&#039;Reset_Handler&#039;&#039;&#039;&#039;&#039; auf Einzelschritt- bzw. Run- Befehle (&#039;&#039;&#039;&#039;&#039;F5, F10, F11&#039;&#039;&#039;&#039;&#039; usw..(siehe &#039;&#039;&#039;&#039;&#039;Debug-Menü&#039;&#039;&#039;&#039;&#039; für alle Möglichkeiten))&lt;br /&gt;
&lt;br /&gt;
*Mit &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039; wird die Debug-Session auch wieder beendet&lt;br /&gt;
&lt;br /&gt;
*Unter &#039;&#039;&#039;&#039;&#039;Debug -&amp;gt; Interfaces -&amp;gt; Target settings&#039;&#039;&#039;&#039;&#039; können Eigenschaften, wie z.B &#039;&#039;&#039;&#039;&#039;Run to main()&#039;&#039;&#039;&#039;&#039; aktiviert werden.&lt;br /&gt;
&lt;br /&gt;
===Projekt als Template abspeichern===&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;File -&amp;gt; Save project as template...&#039;&#039;&#039;&#039;&#039;. Das Template erscheint dann im Projekt-Dialog unter &#039;&#039;&#039;&#039;&#039;User templates&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Das erste Projekt erstellen==&lt;br /&gt;
Hier erkläre ich, wie man am Besten (aus meiner Sicht), ein neues Projekt von Grund auf erstellt, sodass man hinterher, den Controller-Kern über die CMSIS-Library und die Peripherie über die Register steuern kann.&lt;br /&gt;
&lt;br /&gt;
===1. Projekt mit der IDE erstellen===&lt;br /&gt;
Nach der Installation der oben beschriebenen Komponenten erstellt man am besten ein Verzeichnis (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\EmBlocks&#039;&#039;&#039;&#039;&#039;), indem später alle Projekte gespeichert werden. Für Libraries kann man auch noch ein Verzeichnis (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\STM32&#039;&#039;&#039;&#039;&#039;) erstellen, wo alle Libraries gespeichert werden, die man für die Projekt brauchen.&lt;br /&gt;
&lt;br /&gt;
Als nächstes starten man EmBlocks. Bei dem ersten Start öffnet sich ein Fenster, wo verschiedene Compiler angezeigt werden, die Em::Blocks findet. Dort wählt man den &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039; aus und klickt &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039;. Nun sollte sich das Hauptfenster von Em::Blocks öffnen. Über &#039;&#039;&#039;&#039;&#039;Create a new Project&#039;&#039;&#039;&#039;&#039; oder &#039;&#039;&#039;&#039;&#039;File -&amp;gt; New -&amp;gt; Project&#039;&#039;&#039;&#039;&#039; ruft man den Projekt-Dialog auf und kann ein neues Projekt erzeugen.&lt;br /&gt;
&lt;br /&gt;
Auf der Ersten Seite wählen man den &#039;&#039;&#039;&#039;&#039;STmicro-ARM&#039;&#039;&#039;&#039;&#039; Projekt-Typ aus.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_1.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auf der nächsten Seite wird man darauf hingewiesen, dass das der entsprechende Projekt-Typ-Dialog ausgeführt wird. Hier kann man ein Häkchen bei &#039;&#039;&#039;&#039;&#039;Skip this page next time&#039;&#039;&#039;&#039;&#039; setzen und auf &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; klicken.&lt;br /&gt;
&lt;br /&gt;
Im nächsten Schritt wählen man das zuvor erstellt Verzeichnis unter &#039;&#039;&#039;&#039;&#039;Folder to create Project in&#039;&#039;&#039;&#039;&#039; aus, indem später alle Projekt gespeichert werden. Außerdem geben wir dem Projekt einen Namen (z.B. &#039;&#039;&#039;&#039;&#039;FirstProject&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_2.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danach muss man einen Compiler auswählen und bestimmen, welche Projekt-Konfigurationen erszeugt werden sollen. Unter &#039;&#039;&#039;&#039;&#039;Compiler&#039;&#039;&#039;&#039;&#039; wählt man &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039; und man kann das Häkchen bei &#039;&#039;&#039;&#039;&#039;Create &amp;quot;Release&amp;quot; configuration&#039;&#039;&#039;&#039;&#039; entfernen, da diese unnötig ist, die Debug-Konfiguration sollte eig. immer ausreichen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_3.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auf den folgenden Seite wird der Controller ausgewählt. Verwendet man ein STM32F4-Discovery Board müssen folgende Dinge gewählt werden: &#039;&#039;&#039;&#039;&#039;Cortex_M4 (F3xx - F4xx) -&amp;gt; STM32F4xx (Cortex M4 with FPU) -&amp;gt; STM32F407VG&#039;&#039;&#039;&#039;&#039;. Leider sind die Auswahl Möglichkeiten nicht ganz richtig, da auch die F3 Controller einen Cortex M4 Kern und eine FPU haben (Ist aber nicht so wichtig, ist nur eine formale Sache). Außerdem entfernt man das Häkchen bei &#039;&#039;&#039;&#039;&#039;Standard Peripherals Library&#039;&#039;&#039;&#039;&#039; (Wie man die Standard-Peripheral-Library einbindet und verwendet erkläre ich später). Man kann auch das Häkchen bei &#039;&#039;&#039;&#039;&#039;Create hex file for Realease target&#039;&#039;&#039;&#039;&#039; entfernen.&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;Stack Size&#039;&#039;&#039;&#039;&#039; und &#039;&#039;&#039;&#039;&#039;Heap Size&#039;&#039;&#039;&#039;&#039; wird die Größe von Stack und Heap festgelegt. Für eine erste Anwendung kann man die Einstellungen so lassen (Stack-Size: 0x0100 =&amp;gt; 256 Byte Stack und Heap-Size: 0x0000 =&amp;gt; kein Heap). Mit &#039;&#039;&#039;&#039;&#039;Finish&#039;&#039;&#039;&#039;&#039; ist der Projekt Dialog abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_4.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danach sollten sich zwei neue Fenster öffnen, um die Debug-Eigenschaften fest zu legen.&lt;br /&gt;
Verwendet man ein Discovery Board/ST-Link müssen die Einstellungen wie auf dem Bild gewählt werden. Über den Button &#039;&#039;&#039;&#039;&#039;Settings&#039;&#039;&#039;&#039;&#039; öffnet sich das zweite Fenster, falls sich dieses nicht schon von alleine öffnen sollte. Nach den Schließen der Fenster über &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; ist der Projekt Dialog beendet und ein neues Projekt steht zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_5_1.png|Debug Eigenschaften 1. Fenster]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_5_2.png|Debug Eigenschaften 2. Fenster]]&lt;br /&gt;
&lt;br /&gt;
===2. CMSIS-Library und Startup-Code hinzufügen===&lt;br /&gt;
Wenn man sich, nachdem man ein neues Projekt in der IDE erstellt hat, die bereits vorhandenen Dateien im Projekt ansieht, stellt man fest, das bereits ein Ordner &#039;&#039;&#039;&#039;&#039;cmsis&#039;&#039;&#039;&#039;&#039; existiert, der einige wichtige Include-Dateien der CMSIS-Library enthält. Allerdings sind das wirklich nur die wichtigsten Include-Dateien der CMSIS-Library und dazu noch, die aus einer älternen Version. Ich ziehe es deshalb vor die &amp;quot;Mini-CMSIS-Libraray&amp;quot; und die &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c/.h&#039;&#039;&#039;&#039;&#039; Dateien des Projektes durch aktuellere Versionen zu ersetzen. So ist später auch die Integration  von anderen Libraries, wie z.B. der CMSIS-DSP-Libarary einfacher.  &lt;br /&gt;
&lt;br /&gt;
Zunächst gehen man in das Projekt-Verzeichnis und löscht:&lt;br /&gt;
*Den Ordner &#039;&#039;&#039;&#039;&#039;cmsis&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Alle Dateien im Include Verzeichnis &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; im &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner&lt;br /&gt;
&lt;br /&gt;
Außerdem entfernt man auch alle gelöschten Dateien in der IDE aus dem Projekt mit &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Rechts Klick -&amp;gt; Remove file from project&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Es sollte folgende Verzeichnis Struktur überbleiben:&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_6.png|Überbleibende Dateien]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Jetzt müssen die gelöschten Dateien durch die aktuelleren ersetzt werden.&lt;br /&gt;
&lt;br /&gt;
*Dazu kopieren man den gesamten Ordner &#039;&#039;&#039;&#039;&#039;CMSIS&#039;&#039;&#039;&#039;&#039; aus dem CMSIS Download in das Projekt Verzeichnis.&lt;br /&gt;
&lt;br /&gt;
*Aus dem Standard-Peripheral-Library Download kopiert man von &#039;&#039;&#039;&#039;&#039;Libraries\CMSIS\Device\ST\STM32F4xx\Include&#039;&#039;&#039;&#039;&#039; alle Dateien in den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projekt Verzeichnisses&lt;br /&gt;
&lt;br /&gt;
*Aus der Standard-Peripheral-Library kopieren man ebenfalls von &#039;&#039;&#039;&#039;&#039;Libraries\CMSIS\Device\ST\STM32F4xx\Source\Templates&#039;&#039;&#039;&#039;&#039; die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; in den &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner des Projekts&lt;br /&gt;
&lt;br /&gt;
Anschließend müssen die neuen Dateien in der IDE dem Projekt hinzugefügt werden. Dazu benutzt man &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Rechts Klick -&amp;gt; Add files&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
*Aus dem &#039;&#039;&#039;&#039;&#039;CMSIS&#039;&#039;&#039;&#039;&#039; Ordner im Projekt Verzeichnis werden aus den Unterorder &#039;&#039;&#039;&#039;&#039;Include&#039;&#039;&#039;&#039;&#039; folgende Dateien dem Projekt hinzugefügt:&lt;br /&gt;
**arm_common_tables.h&lt;br /&gt;
**arm_const_structs.h&lt;br /&gt;
**arm_math.h&lt;br /&gt;
**core_cm4.h&lt;br /&gt;
**core_cm4_simd.h&lt;br /&gt;
**core_cmFunc.h&lt;br /&gt;
**core_cmInstr.h&lt;br /&gt;
*Alle Dateien aus den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projektes&lt;br /&gt;
*Die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; aus dem &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner&lt;br /&gt;
&lt;br /&gt;
So sollte die Struktur dann aussehen:&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_7.png|Anwenungs-Grundgerüst]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Da einige Dateien der Libraries später bearbeitet werden müssen und Schreibgeschützt sind, weise ich hier schonmal darauf hin, das der Schreibschutz in der IDE über &#039;&#039;&#039;&#039;&#039;Rechts Klick auf die Datei -&amp;gt; Properties -&amp;gt; Häkchen bei &amp;quot;File is read only&amp;quot; entfernen&#039;&#039;&#039;&#039;&#039; entfert werden kann.&lt;br /&gt;
&lt;br /&gt;
Damit die IDE die Header-Dateien der CMSIS Library auch finden kann, weil diese ja nicht im standard Include Ordner &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; liegen, muss unter &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Build Options -&amp;gt; Search Directories&#039;&#039;&#039;&#039;&#039; der Pfad &#039;&#039;&#039;&#039;&#039;CMSIS\Include&#039;&#039;&#039;&#039;&#039; hinzugefügt werden.&lt;br /&gt;
&lt;br /&gt;
Compiliert man jetzt das Projekt mit &#039;&#039;&#039;&#039;&#039;F7&#039;&#039;&#039;&#039;&#039; gibt es ein paar Fehler Meldungen, weil keine Controller-Reihe ausgewählt wurde. Ebenfalls unter &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Build Options -&amp;gt; Compiler Settings -&amp;gt; #defines&#039;&#039;&#039;&#039;&#039; wird der Define &#039;&#039;&#039;&#039;&#039;STM32F40_41xxx&#039;&#039;&#039;&#039;&#039; hinzugefügt.&lt;br /&gt;
&lt;br /&gt;
Beim erneuten Compilieren sollten sich nun keine neuen Fehler ergeben.&lt;br /&gt;
&lt;br /&gt;
===3. Das erste Programm===&lt;br /&gt;
Nachdem ein grundsätzliches &amp;quot;Gerüst&amp;quot; fertig ist, kann man den ersten Code schreiben.&lt;br /&gt;
main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC-&amp;gt;AHB1ENR |= RCC_AHB1ENR_GPIODEN;    //Takt für GPIO aktivieren&lt;br /&gt;
    GPIOD-&amp;gt;MODER |= GPIO_MODER_MODER15_0;   //GPIOD Pin15 als Ausgang&lt;br /&gt;
    GPIOD-&amp;gt;BSRRL |= GPIO_BSRR_BS_15;        //GPIOD Pin15 auf High ziehen&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039; wird dann der Debugger gestartet. Hat der Debugger das Projekt erfolgreich übertragen kann die Ausführung mit &#039;&#039;&#039;&#039;&#039;F5&#039;&#039;&#039;&#039;&#039; begonnen werden.&lt;br /&gt;
&lt;br /&gt;
==Libraries einbinden/verwenden==&lt;br /&gt;
===Einbinden der Standard-Peripheral-Library===&lt;br /&gt;
Um nicht immer die einzelnen Register, wie im ersten &amp;quot;bare-metal&amp;quot; Beispiel, aus dem Reference-Manual zu suchen und zu beschreiben, gibt es von ST die Standard Peripheral Library, die diese Aufgaben übernimmt und mit der sich die &amp;quot;normale/grundlegende&amp;quot; (Alles außer USB und Ethernet) Peripherie recht einfach steuern lässt. Um die Library zu verwenden erzeugt man wie oben beschrieben ein neues Grundgerüst und kopiert als erstes den Ordner &#039;&#039;&#039;&#039;&#039;Libraries\STM32F4xx_StdPeriph_Driver&#039;&#039;&#039;&#039;&#039; aus dem Standard-Peripheral-Library Download in das Projekt-Verzeichnis. Außerdem muss man die Datei &#039;&#039;&#039;&#039;&#039;Project\STM32F4xx_StdPeriph_Templates\stm32f4xx_conf.h&#039;&#039;&#039;&#039;&#039; ebenfalls aus dem Standard-Peripheral-Library Download in den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projektes kopieren. In der IDE fügt man den Include-Path &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\inc&#039;&#039;&#039;&#039;&#039; hinzufügen, wie bei der CMSIS-Library (s.o.).&lt;br /&gt;
Außerdem muss noch &#039;&#039;&#039;&#039;&#039;USE_STDPERIPH_DRIVER&#039;&#039;&#039;&#039;&#039; als Define in der IDE hinzugefügt werden (s.o.).&lt;br /&gt;
Danach fügt man die Source- und Include-Dateien aus dem Ordner &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\inc&#039;&#039;&#039;&#039;&#039; und &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\src&#039;&#039;&#039;&#039;&#039; dem Project mit &#039;&#039;&#039;&#039;&#039;&amp;lt;Project Name&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Add files&#039;&#039;&#039;&#039;&#039; hinzu, allerdings nur die, für welche auch der Controller die entsprechende Peripherie besitzt. Beim STM32F4-Discovery Board / STM32F407VG Controller dürfen also nicht folgende Dateien nicht mit hinzugefügt werden, weil diese Peripherie nur bei anderen Controller vorhanden ist:&lt;br /&gt;
&lt;br /&gt;
*stm32f4xx_dma2d.c/.h&lt;br /&gt;
*stm32f4xx_fmc.c/.h&lt;br /&gt;
*stm32f4xx_ltdc.c/.h&lt;br /&gt;
*stm32f4xx_sai.c/.h&lt;br /&gt;
&lt;br /&gt;
Daraus resultiert folgende Struktur:&lt;br /&gt;
&lt;br /&gt;
[[Datei:stdperiphlib_2.png|Header-Struktur]] [[Datei:stdperiphlib_1.png|Source-Struktur]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Anschließen kann die Standard-Peripheral-Library benutz werden.&lt;br /&gt;
main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);&lt;br /&gt;
&lt;br /&gt;
    GPIO_InitTypeDef GPIOD_InitStructure;&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Mode = GPIO_Mode_OUT;     //Als Ausgang&lt;br /&gt;
    GPIOD_InitStructure.GPIO_OType = GPIO_OType_PP;    //Push-Pull Betrieb&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Pin = GPIO_Pin_15;        //Pin 15 (STM32F4-Discovery: Blaue LED)&lt;br /&gt;
    GPIOD_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;  //Kein Pull-Up oder Pull-Down Widerstand aktiviert&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Speed = GPIO_Speed_25MHz; //25MHz Update-Rate&lt;br /&gt;
    GPIO_Init(GPIOD, &amp;amp;GPIOD_InitStructure);&lt;br /&gt;
&lt;br /&gt;
    GPIO_SetBits(GPIOD, GPIO_Pin_15);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Einbinden der DSP-Library===&lt;br /&gt;
STM32F3 / STM32F4 Microcontroller haben neben der FPU noch einen Digital-Signal-Processor (DSP). Die DSP dient hauptsächlich dazu, viele Daten schnell zu verarbeiten (z.B. Video- oder Audiosignal). Der CMSIS-Download beinhaltet dazu neben der eigentlichen CMSIS-Library auch noch eine DSP-Library. Diese Library stellt sowohl einfache, mathematische Funktionen wie addieren, multiplizieren usw. als auch komplexe Funktionen, wie z.B  einen IIR-Filter, zur Verfügung. Die DSP-Library ist weiter aufgeteilt in kleinere Module, wie z.B. BasicMathFunctions, FilteringFunctions usw. (siehe &#039;&#039;&#039;&#039;&#039;CMSIS\DSP-Library\Source&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
Um die DSP-Library zu verwenden müssen nur die Source-Files des benötigten Moduls einbinden.&lt;br /&gt;
(&#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Add files...&#039;&#039;&#039;&#039;&#039;). Außerdem muss in der &#039;&#039;&#039;&#039;&#039;main.c&#039;&#039;&#039;&#039;&#039; der Include &#039;&#039;&#039;&#039;&#039;arm_math.h&#039;&#039;&#039;&#039;&#039; eingebunden werden. Aus irgendeinem Grund gibt es dann jedoch die Warnung: &amp;quot;Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)&amp;quot;. Ich hab noch nicht rausgefunden, wieso diese Warnung auftaucht. Die Warnung verschwindet, wenn man in der &#039;&#039;&#039;&#039;&#039;Build options...&#039;&#039;&#039;&#039;&#039; das Define &#039;&#039;&#039;&#039;&#039;__FPU_PRESENT&#039;&#039;&#039;&#039;&#039; hinzufügt (Ich weiß selber das das keine schöne Lösung ist, eine andere hab ich jedoch noch nicht gefunden). Jetzt kann die DSP-Library verwedet werden. Das Beispiel multipliziert zwei Buffer miteinander. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
#include &amp;quot;arm_math.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    float32_t x[1024];&lt;br /&gt;
    float32_t y[1024];&lt;br /&gt;
    float32_t z[1024];&lt;br /&gt;
&lt;br /&gt;
    for(uint16_t i = 0; i &amp;lt; 1024; i++)&lt;br /&gt;
    {&lt;br /&gt;
        x[i] = i;&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for(uint16_t i = 0; i &amp;lt; 1024; i++)&lt;br /&gt;
    {&lt;br /&gt;
        y[i] = PI;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    arm_mult_f32(x, y, z, 1024);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Startup-Code, Linker-Script, Takt, FPU usw.==&lt;br /&gt;
===Startup-Code===&lt;br /&gt;
Em::Blocks fügt standardmäßig einen Startup-Code mit in das Projekt ein. Die wichtigsten Dinge die darin erledigt werden sind folgende:&lt;br /&gt;
&lt;br /&gt;
*Stack und Heap wird angelgt&lt;br /&gt;
*Die Vector-Table wird angelegt&lt;br /&gt;
*Ein Default Reset-Handler wird implementiert, dieser erledigt folgende aufgaben:&lt;br /&gt;
**Kopieren der definierten Daten aus dem Flash in den SRAM&lt;br /&gt;
**&#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; wird aufgerfen, wenn &#039;&#039;&#039;&#039;&#039;__NO_SYSTEM_INIT&#039;&#039;&#039;&#039;&#039; nicht definiert ist&lt;br /&gt;
**Sprung in die &#039;&#039;&#039;&#039;&#039;main()&#039;&#039;&#039;&#039;&#039; Funktion&lt;br /&gt;
*Allen anderen Interrupt-Handler wird eine Default-Funktion &#039;&#039;&#039;&#039;&#039;def_irq_handler&#039;&#039;&#039;&#039;&#039; mit einer &#039;&#039;&#039;&#039;&#039;while(1)&#039;&#039;&#039;&#039;&#039;-Schleife zugewiesen, falls kein anderer Interrupt-Handler existiert.&lt;br /&gt;
&lt;br /&gt;
Normalerweise muss am Startup-Code nichts verändert werden.&lt;br /&gt;
&lt;br /&gt;
===Linker-Script===&lt;br /&gt;
Em::Blocks stellt zwei fertige Linker-Scripts bereit, eins für die Ausführung des Programmes aus dem Flash (&#039;&#039;&#039;&#039;&#039;*_flash.ld&#039;&#039;&#039;&#039;&#039;), das andere für die Ausführung aus dem SRAM (&#039;&#039;&#039;&#039;&#039;*_sram.ld&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Normalerweise muss auch hier nichts geändert werden, es sei den Daten sollen in bestimmten Adressbereichen abgelegt werden (z.B. im Core-Coupled RAM), was ich später noch zum Tutorial hinzufüge.&lt;br /&gt;
&lt;br /&gt;
===Der Takt===&lt;br /&gt;
Jeder Controller oder Prozessor braucht einen Takt, indem er die einzelnen Maschinen-Befehle abarbeiten kann.&lt;br /&gt;
Bei den STM32 Mikrocontrollern kann dieser Takt aus verschiedenen Quellen kommen:&lt;br /&gt;
&lt;br /&gt;
1. High Speed Internal Oszillator (HSI)&lt;br /&gt;
&lt;br /&gt;
2. High Speed External Oszillator (HSE)&lt;br /&gt;
&lt;br /&gt;
3. Low Speed Internal Oszillator (LSI)&lt;br /&gt;
&lt;br /&gt;
4. Low Speed External Oszillator (LSE)&lt;br /&gt;
&lt;br /&gt;
5. Phase-Locked Loop (PLL) (generiert den Takt aus den ersten vier Taktquellen durch Teiler und Faktoren)&lt;br /&gt;
&lt;br /&gt;
Nach einem Reset wird der Controller aus der HSI Taktquelle versorgt (16MHz beim STM32F407VG). Um die voll Performance des Controllers zu erreichen muss die PLL verwendet werden, welche den Takt durch geschickte Teiler und Faktoren vervielfältigt, sodass am Ende der Controller mit der maximalen Taktfrequenz läuft. Die notwendige Initialisierung der PLL findet in der Funktion &#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; statt. Die PLL erzeugt zunächst einen Basistakt:&lt;br /&gt;
&lt;br /&gt;
PLL_VCO = (F_HSE / PLL_M) * PLL_N&lt;br /&gt;
&lt;br /&gt;
Aus diesem Takt wird dann der Takt für den Controller-Kern abgeleitet:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = PLL_VCO / PLL_P&lt;br /&gt;
&lt;br /&gt;
Und der Takt für SDIO / USB / RNG (48MHz):&lt;br /&gt;
&lt;br /&gt;
48MHz = PLL_VCO / PLL_Q&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Durch weiter Teiler werden, die Takte für die einzelnen Busse erzeugt, da diese nicht alle beliebig schnell betrieben werden dürfen.&lt;br /&gt;
&lt;br /&gt;
Genaue Angaben findet man zu dem jeweiligen Clock-System des Controllers im Reference Manual.&lt;br /&gt;
&lt;br /&gt;
Ein Blick in den &amp;quot;Kommentar-Header&amp;quot; verrät, dass von einem externen (HSE) Oszillator von 25MHz ausgegangen wird, der die PLL versorgen soll.&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((25MHz / PLL_M(25)) * PLL_N(336)) / PLL_P(2) = 168MHz&lt;br /&gt;
&lt;br /&gt;
Allerdings stimmt diese Rechnung natürlich nur, wenn wirklich ein 25MHz Quarz am Controller angeschlossen ist. Auf dem STM32F4-Discovery Board befindet sich aber nur ein 8MHz Quarz. Demnach gilt:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((8MHz / PLL_M(25)) * PLL_N(336)) / PLL_P(2) = 53.76MHz&lt;br /&gt;
&lt;br /&gt;
Der Controller läuft also nur mit 53.76MHz, wenn wie ober beschrieben ein Projekt erstellt wird. Allerdings kann dieses Problem durch ändern von den betroffen Defines behoben werden:&lt;br /&gt;
 &lt;br /&gt;
*Dazu geht man in die &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; Datei und passt zur Vollständigkeit erstmal die zum Controller passende Tabelle im &amp;quot;Kommentar-Header&amp;quot; an (Z.57f):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      HSE Frequency(Hz)                      | 8000000&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      PLL_M                                  | 8&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Danach passt man den PPL_M Define (Z.254) an:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/************************* PLL Parameters *************************************/&lt;br /&gt;
/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */&lt;br /&gt;
#define PLL_M      8&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Außerdem muss man den HSE_VALUE Define in der &#039;&#039;&#039;&#039;&#039;inc/stm32f4xx.h&#039;&#039;&#039;&#039;&#039; angepasst werden (Z.122):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#if !defined  (HSE_VALUE)&lt;br /&gt;
  #define HSE_VALUE    ((uint32_t)8000000) /*!&amp;lt; Value of the External oscillator in Hz */&lt;br /&gt;
&lt;br /&gt;
#endif /* HSE_VALUE */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine neue Berechnung zeigt:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((8MHz / PLL_M(8)) * PLL_N(336)) / PLL_P(2) = 168MHz&lt;br /&gt;
&lt;br /&gt;
Jetzt läuft der Controller mit maximaler Geschwindigkeit.&lt;br /&gt;
&lt;br /&gt;
Die Theorie wird durch folgendes Programm verifiziert. Der geviertelte System-Takt SYSCLK wir am Pin PC9 ausgegeben. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);&lt;br /&gt;
&lt;br /&gt;
    GPIO_InitTypeDef GPIOC_InitStructure;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Mode = GPIO_Mode_AF;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_OType = GPIO_OType_PP;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Pin = GPIO_Pin_9;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;&lt;br /&gt;
    GPIO_Init(GPIOC, &amp;amp;GPIOC_InitStructure);&lt;br /&gt;
&lt;br /&gt;
    RCC_MCO2Config(RCC_MCO2Source_SYSCLK, RCC_MCO2Div_4);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Die FPU===&lt;br /&gt;
====Allgemeines====&lt;br /&gt;
Damit die FPU richtig verwendet wird, müssen normalerweise zwei Bedingungen erfüllt sein:&lt;br /&gt;
&lt;br /&gt;
1. Der Controller muss in der Initialisierung-Funktion &#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; in &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; die FPU Hardware-seitig aktivieren&lt;br /&gt;
&lt;br /&gt;
2. Damit die FPU auch was zu tuen bekommt, müssen vom Compiler FPU-Instructions erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
Die Em::Blocks IDE verwendet standardmäßig die FPU, wenn eine Vorhanden ist. Hier wird die FPU Hardware-seitig aktiviert (&#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; Z.341):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* FPU settings ------------------------------------------------------------*/&lt;br /&gt;
  #if (__FPU_PRESENT == 1) &amp;amp;&amp;amp; (__FPU_USED == 1)&lt;br /&gt;
    SCB-&amp;gt;CPACR |= ((3UL &amp;lt;&amp;lt; 10*2)|(3UL &amp;lt;&amp;lt; 11*2));  /* set CP10 and CP11 Full Access */&lt;br /&gt;
  #endif&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
__FPU_PRESENT wird in der &#039;&#039;&#039;&#039;&#039;stm32f4xx.h&#039;&#039;&#039;&#039;&#039; definiert.&lt;br /&gt;
__FPU_USED wird von der IDE übernommen (siehe Build-Log): &#039;&#039;&#039;&#039;&#039;-D__FPU_USED&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Außerdem wird der Compiler von der IDE standardmäßig mit dem Argument &#039;&#039;&#039;&#039;&#039;-mfloat-abi=hard&#039;&#039;&#039;&#039;&#039; aufgerufen, wodurch FPU-Instructions erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
====FPU abschalten====&lt;br /&gt;
Um die FPU ab zu schalten (Mir würde jetzt nur Strom sparen als Grund einfallen) geht man wie folgt vor:&lt;br /&gt;
&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick Build options -&amp;gt; Device -&amp;gt; Policy&#039;&#039;&#039;&#039;&#039; wählt man &#039;&#039;&#039;&#039;&#039;Use target settings&#039;&#039;&#039;&#039;&#039; und über nimmt die Einstellungen, die vorher dort eingetragen waren, allerdings lässt man das Feld &#039;&#039;&#039;&#039;&#039;FP-hardware&#039;&#039;&#039;&#039;&#039; frei.&lt;br /&gt;
&lt;br /&gt;
[[Datei:fpu_1.png|FPU Abschalten Schritt 1]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;Compiler Settings -&amp;gt; Policy&#039;&#039;&#039;&#039;&#039; wählt man dann &#039;&#039;&#039;&#039;&#039;Use target options only&#039;&#039;&#039;&#039;&#039;. Dann kann man unter &#039;&#039;&#039;&#039;&#039;Categories&#039;&#039;&#039;&#039;&#039; die Option &#039;&#039;&#039;&#039;&#039;ARM FPU architecture&#039;&#039;&#039;&#039;&#039; auswählen. Dort stehen dann drei Möglichkeiten für die FPU zur Verfügung:&lt;br /&gt;
&lt;br /&gt;
1. Software-FPU-Library für Gleitkomma-Berechnung verwenden - Keine FPU-Instructions werden generiert (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=soft&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
2. Eine Mischung aus Software- und Hardware-FPU wird verwendet (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=softfp&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
3. Hardware-FPU wird für Gleitkomma-Berechnungen verwendet (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=hard&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
[[Datei:fpu_2.png|FPU Abschalten Schritt 2]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Um die FPU ab zu schalten wählt man natürlich die erste Möglichkeit.&lt;br /&gt;
Bei der 2. und 3. Möglichkeit fügt die IDE auch den Define &#039;&#039;&#039;&#039;&#039;__FPU_USED&#039;&#039;&#039;&#039;&#039; hinzu. Bei Der ersten Möglichkeit nicht. Der Code muss also nicht verändert / auskommentiert werden.&lt;br /&gt;
&lt;br /&gt;
Um die FPU wieder zu aktivieren müssen alle Schritte wieder rückgängig gemacht werden.&lt;br /&gt;
&lt;br /&gt;
Am besten ist es einfach mal alle Möglichkeiten im Einzelschritt durch zu probieren. Dann stellt man schnell fest, ob die FPU aktiviert wir oder nicht. Ein Blick in den erweiterten &#039;&#039;&#039;&#039;&#039;Build-Log&#039;&#039;&#039;&#039;&#039; gibt auch schnell Aufschluss darüber, wie der Compiler aufgerufen wird (siehe Kapitel [http://www.mikrocontroller.net/articles/STM32_-_Einstieg_mit_Em::Blocks#Compilieren Compilieren]).&lt;br /&gt;
&lt;br /&gt;
====Test Programm für die FPU====&lt;br /&gt;
Hier ein kleines Testprogramm, dass misst wie viele Taktzyklen für eine Gleitkomma-Multiplikation gebraucht werden. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define CORE_SysTickEn()    (*((u32*)0xE0001000)) = 0x40000001&lt;br /&gt;
#define CORE_SysTickDis()   (*((u32*)0xE0001000)) = 0x40000000&lt;br /&gt;
#define CORE_GetSysTick()   (*((u32*)0xE0001004))&lt;br /&gt;
&lt;br /&gt;
uint32_t t1, t2, dt;&lt;br /&gt;
float x, y, z;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    x = 53.64f;&lt;br /&gt;
    y = 0.27f;&lt;br /&gt;
&lt;br /&gt;
    CORE_SysTickEn();&lt;br /&gt;
    t1 = CORE_GetSysTick();&lt;br /&gt;
&lt;br /&gt;
    z = x * y;&lt;br /&gt;
&lt;br /&gt;
    t2 = CORE_GetSysTick();&lt;br /&gt;
    CORE_SysTickDis();&lt;br /&gt;
&lt;br /&gt;
    dt = (t2 - t1) - 9; //9 Takt-Zyklen werden für die Messung gebraucht &lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Booten aus dem SRAM==&lt;br /&gt;
STM32 Controller haben die Möglichkeit Code aus dem Flash als auch aus dem SRAM auszuführen. Um eine Anwenung per Debugger in des SRAM zu laden sind nur wenige Schritte erforderlich:&lt;br /&gt;
&lt;br /&gt;
*Um das Linkerscript für den SRAM zu verwenden geht man zu: &#039;&#039;&#039;&#039;&#039;Build options... -&amp;gt; Device&#039;&#039;&#039;&#039;&#039; dort wählt man unter &#039;&#039;&#039;&#039;&#039;Policy&#039;&#039;&#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;Use target settings&#039;&#039;&#039;&#039;&#039; aus und übernimmt die vorherigen Einstellungen, nur unter &#039;&#039;&#039;&#039;&#039;Linker script*&#039;&#039;&#039;&#039;&#039; gibt man &#039;&#039;&#039;&#039;&#039;.\stm32f407vg_sram.ld&#039;&#039;&#039;&#039;&#039; an&lt;br /&gt;
&lt;br /&gt;
*Dann muss man noch unter &#039;&#039;&#039;&#039;&#039;Debug -&amp;gt; Interfaces -&amp;gt; Settings&#039;&#039;&#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;Vector table start&#039;&#039;&#039;&#039;&#039; auf 0x20000000 ändern und &#039;&#039;&#039;&#039;&#039;Execute from RAM&#039;&#039;&#039;&#039;&#039; auswählen.&lt;br /&gt;
&lt;br /&gt;
Anschließend kann man die Anwendung ganz normal debuggen. Nach einem Reset muss die Anwenung erneut mit dem Debugger gestartet werden.&lt;br /&gt;
&lt;br /&gt;
=Fortsetzung folgt..=&lt;br /&gt;
Kritik, Wünsche usw. sind gerne erwünscht, am besten hier in den Thread posten: [http://www.mikrocontroller.net/topic/323750 Neues STM32 Tutorial]&lt;br /&gt;
&lt;br /&gt;
[[Category:ARM]]&lt;br /&gt;
[[Category:STM32]]&lt;/div&gt;</summary>
		<author><name>Avrprogger</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=STM32_-_Einstieg_mit_Em::Blocks&amp;diff=81543</id>
		<title>STM32 - Einstieg mit Em::Blocks</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=STM32_-_Einstieg_mit_Em::Blocks&amp;diff=81543"/>
		<updated>2014-02-11T16:40:48Z</updated>

		<summary type="html">&lt;p&gt;Avrprogger: sdf&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In diesem Tutorial werde ich versuchen, möglichst einfach, die ersten Schritte zur Entwicklung von STM32 Anwenungen mit der Em::Blocks IDE zu erklären. Hier soll nicht so stark auf die einzelnen Peripherie-Module der Controller eingegangen werden, sondern mehr auf die IDE und die verschieden Libraries, wie die CMSIS Library, die DSP-Library, die Standard-Peripheral-Library, die USB-Library und vllt. über Ethernet. Ich denke ein Kapitel zu FreeRTOS wird es auch geben. Auserdem steht im Vordergrund Sachen wie z.B. booten aus dem SRAM, In-Application-Programming, FPU, Core-Coupled-RAM usw. Mal sehn wie weit ich komme ;)&lt;br /&gt;
&lt;br /&gt;
==Die Entwicklungsumgebung==&lt;br /&gt;
===Hardware===&lt;br /&gt;
Zum testen der Anwendungen, benutze ich das STM32F4-Discovery Board, welches einen Debugger, Peripherie und natürlich einen STM32 Controller (STM32F407VGT6) enthält. Deshalb sind alle Beispiele hier für den STM32F407VG Controller ausgelegt, können aber meisten 1:1 auf andere Controller portiert werden. Ich werde auch möglichsts keine STM32F4-Discovery Board spezifischen Libraries verwenden, damit der Portierungs-Vorgang möglichsts einfach bleibt.&lt;br /&gt;
&lt;br /&gt;
===Software===&lt;br /&gt;
In diesem Tutorial verwende ich [http://www.emblocks.org/ Em::Blocks] als IDE. Em::Blocks ist eine kostenlose, uneingeschränkte IDE, die alle STM32 Mikrcontroller unterstützt und sehr einfach zu bedienen ist.&lt;br /&gt;
nach dem Download kann die IDE per Dialog, sehr einfach, installiert werden. Als Compiler beinhaltet Em::Blocks den &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
Die IDE unterstützt zurzeit den ST-Link, den J-Link und es gibt eine Generic-Vorlage, durch welche andere Debugger konfiguriert werden können.&lt;br /&gt;
&lt;br /&gt;
Außerdem muss noch der passende Treiber für den Debugger installiert werden. Verwendet man ein Discovery-Board muss der [http://www.st.com/web/catalog/tools/FM146/CL1984/SC724/SS1677/PF251168 ST-Link/V2]-Treiber heruntergeladen und installiert werden. (Die Installation muss evtl. als Administrator ausgeführt werden, da sonst die Installation unvollständig wird.) Nach der Installation des Treibers kann man den Debugger über die entsprechende USB Schnittstelle an den PC anschließen und es sollte die Meldung von Windows kommen, dass der richtige Treiber gefunden wurde.&lt;br /&gt;
&lt;br /&gt;
===Libraries===&lt;br /&gt;
Zum programmieren benötigt man noch die [http://www.arm.com/products/processors/cortex-m/cortex-microcontroller-software-interface-standard.php CMSIS] und die Standard-Peripheral-Library (z.B. für die F4 Controller [http://www.st.com/stonline/stappl/productcatalog/app?page=partNumberSearchPage&amp;amp;levelid=SS1577&amp;amp;parentid=1743&amp;amp;resourcetype=SW Standard-Peripheral-Library-F4]), die man am besten in einen Ordner (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\STM32&#039;&#039;&#039;&#039;&#039;) entpackt&lt;br /&gt;
&lt;br /&gt;
==Basis-Wissen zur IDE==&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von Dateien zum Projekt===&lt;br /&gt;
Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf &amp;lt;ProjektName&amp;gt; -&amp;gt; Add files...&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Enfernen von Dateien aus dem Projekt===&lt;br /&gt;
Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf die Datei / mehrere Dateien auswählen -&amp;gt; Remove file from project&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
Die Dateien werden lediglich aus dem Projekt entfernt und nicht von der Festplatte gelöscht.&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von Include-Pfaden===&lt;br /&gt;
Sofern die Include-Datei(en) nicht im standard Include-Ordner &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; des Projektes liegen, muss man den Pfad zum Projekt hinzufügen, damit der Compiler die Include-Dateien später auch finden kann. Man geht wie folgt vor: Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; Search Directories -&amp;gt; Add&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von globalen Defines zum Build===&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; #defines&#039;&#039;&#039;&#039;&#039; können globale Defines hinzugefügt werden.&lt;br /&gt;
&lt;br /&gt;
===Compilieren===&lt;br /&gt;
Entweder über das &#039;&#039;&#039;&#039;&#039;Build&#039;&#039;&#039;&#039;&#039; Menü oder über &#039;&#039;&#039;&#039;&#039;F7&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Um eine genau Ausgabe des Compiler-Aufrufes mit allen Argumenten zu bekommen, geht man im &#039;&#039;&#039;&#039;&#039;Settings&#039;&#039;&#039;&#039;&#039; Menü auf &#039;&#039;&#039;&#039;&#039;Tools...&#039;&#039;&#039;&#039;&#039; und dann auf &#039;&#039;&#039;&#039;&#039;Toolchain executables&#039;&#039;&#039;&#039;&#039;. Ganz unten, unter &#039;&#039;&#039;&#039;&#039;Logging&#039;&#039;&#039;&#039;&#039; kann man dann &#039;&#039;&#039;&#039;&#039;Full command line&#039;&#039;&#039;&#039;&#039; auswählen.&lt;br /&gt;
&lt;br /&gt;
====Compiler Optionen====&lt;br /&gt;
=====Optimierung=====&lt;br /&gt;
Standardmäßig verwendet Em::Blocks keine Optimierung. Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; Categories: Optimization&#039;&#039;&#039;&#039;&#039; kann zwischen verschieden Optimierungen ausgewählt werden.&lt;br /&gt;
&lt;br /&gt;
=====Verschiedene C-Standards=====&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; Categories: Language standard&#039;&#039;&#039;&#039;&#039; kann man zwischen verschieden C-Standard auswählen, wie z.B, C99.&lt;br /&gt;
(Mit C99 können auch die Lauf-Variable in der for-Schleife deklariert werden: for(int i;..))&lt;br /&gt;
&lt;br /&gt;
===Debuggen===&lt;br /&gt;
*Als erstes den Debugger starten über das &#039;&#039;&#039;&#039;&#039;Debug&#039;&#039;&#039;&#039;&#039; Menü und &#039;&#039;&#039;&#039;&#039;Start/stop Debug Session&#039;&#039;&#039;&#039;&#039; oder über &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
*Danach läuft die Anwendung auf dem Controller und warten im &#039;&#039;&#039;&#039;&#039;Reset_Handler&#039;&#039;&#039;&#039;&#039; auf Einzelschritt- bzw. Run- Befehle (&#039;&#039;&#039;&#039;&#039;F5, F10, F11&#039;&#039;&#039;&#039;&#039; usw..(siehe &#039;&#039;&#039;&#039;&#039;Debug-Menü&#039;&#039;&#039;&#039;&#039; für alle Möglichkeiten))&lt;br /&gt;
&lt;br /&gt;
*Mit &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039; wird die Debug-Session auch wieder beendet&lt;br /&gt;
&lt;br /&gt;
*Unter &#039;&#039;&#039;&#039;&#039;Debug -&amp;gt; Interfaces -&amp;gt; Target settings&#039;&#039;&#039;&#039;&#039; können Eigenschaften, wie z.B &#039;&#039;&#039;&#039;&#039;Run to main()&#039;&#039;&#039;&#039;&#039; aktiviert werden.&lt;br /&gt;
&lt;br /&gt;
===Projekt als Template abspeichern===&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;File -&amp;gt; Save project as template...&#039;&#039;&#039;&#039;&#039;. Das Template erscheint dann im Projekt-Dialog unter &#039;&#039;&#039;&#039;&#039;User templates&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Das erste Projekt erstellen==&lt;br /&gt;
Hier erkläre ich, wie man am Besten (aus meiner Sicht), ein neues Projekt von Grund auf erstellt, sodass man hinterher, den Controller-Kern über die CMSIS-Library und die Peripherie über die Register steuern kann.&lt;br /&gt;
&lt;br /&gt;
===1. Projekt mit der IDE erstellen===&lt;br /&gt;
Nach der Installation der oben beschriebenen Komponenten erstellt man am besten ein Verzeichnis (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\EmBlocks&#039;&#039;&#039;&#039;&#039;), indem später alle Projekte gespeichert werden. Für Libraries kann man auch noch ein Verzeichnis (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\STM32&#039;&#039;&#039;&#039;&#039;) erstellen, wo alle Libraries gespeichert werden, die man für die Projekt brauchen.&lt;br /&gt;
&lt;br /&gt;
Als nächstes starten man EmBlocks. Bei dem ersten Start öffnet sich ein Fenster, wo verschiedene Compiler angezeigt werden, die Em::Blocks findet. Dort wählt man den &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039; aus und klickt &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039;. Nun sollte sich das Hauptfenster von Em::Blocks öffnen. Über &#039;&#039;&#039;&#039;&#039;Create a new Project&#039;&#039;&#039;&#039;&#039; oder &#039;&#039;&#039;&#039;&#039;File -&amp;gt; New -&amp;gt; Project&#039;&#039;&#039;&#039;&#039; ruft man den Projekt-Dialog auf und kann ein neues Projekt erzeugen.&lt;br /&gt;
&lt;br /&gt;
Auf der Ersten Seite wählen man den &#039;&#039;&#039;&#039;&#039;STmicro-ARM&#039;&#039;&#039;&#039;&#039; Projekt-Typ aus.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_1.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auf der nächsten Seite wird man darauf hingewiesen, dass das der entsprechende Projekt-Typ-Dialog ausgeführt wird. Hier kann man ein Häkchen bei &#039;&#039;&#039;&#039;&#039;Skip this page next time&#039;&#039;&#039;&#039;&#039; setzen und auf &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; klicken.&lt;br /&gt;
&lt;br /&gt;
Im nächsten Schritt wählen man das zuvor erstellt Verzeichnis unter &#039;&#039;&#039;&#039;&#039;Folder to create Project in&#039;&#039;&#039;&#039;&#039; aus, indem später alle Projekt gespeichert werden. Außerdem geben wir dem Projekt einen Namen (z.B. &#039;&#039;&#039;&#039;&#039;FirstProject&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_2.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danach muss man einen Compiler auswählen und bestimmen, welche Projekt-Konfigurationen erszeugt werden sollen. Unter &#039;&#039;&#039;&#039;&#039;Compiler&#039;&#039;&#039;&#039;&#039; wählt man &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039; und man kann das Häkchen bei &#039;&#039;&#039;&#039;&#039;Create &amp;quot;Release&amp;quot; configuration&#039;&#039;&#039;&#039;&#039; entfernen, da diese unnötig ist, die Debug-Konfiguration sollte eig. immer ausreichen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_3.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auf den folgenden Seite wird der Controller ausgewählt. Verwendet man ein STM32F4-Discovery Board müssen folgende Dinge gewählt werden: &#039;&#039;&#039;&#039;&#039;Cortex_M4 (F3xx - F4xx) -&amp;gt; STM32F4xx (Cortex M4 with FPU) -&amp;gt; STM32F407VG&#039;&#039;&#039;&#039;&#039;. Leider sind die Auswahl Möglichkeiten nicht ganz richtig, da auch die F3 Controller einen Cortex M4 Kern und eine FPU haben (Ist aber nicht so wichtig, ist nur eine formale Sache). Außerdem entfernt man das Häkchen bei &#039;&#039;&#039;&#039;&#039;Standard Peripherals Library&#039;&#039;&#039;&#039;&#039; (Wie man die Standard-Peripheral-Library einbindet und verwendet erkläre ich später). Man kann auch das Häkchen bei &#039;&#039;&#039;&#039;&#039;Create hex file for Realease target&#039;&#039;&#039;&#039;&#039; entfernen.&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;Stack Size&#039;&#039;&#039;&#039;&#039; und &#039;&#039;&#039;&#039;&#039;Heap Size&#039;&#039;&#039;&#039;&#039; wird die Größe von Stack und Heap festgelegt. Für eine erste Anwendung kann man die Einstellungen so lassen (Stack-Size: 0x0100 =&amp;gt; 256 Byte Stack und Heap-Size: 0x0000 =&amp;gt; kein Heap). Mit &#039;&#039;&#039;&#039;&#039;Finish&#039;&#039;&#039;&#039;&#039; ist der Projekt Dialog abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_4.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danach sollten sich zwei neue Fenster öffnen, um die Debug-Eigenschaften fest zu legen.&lt;br /&gt;
Verwendet man ein Discovery Board/ST-Link müssen die Einstellungen wie auf dem Bild gewählt werden. Über den Button &#039;&#039;&#039;&#039;&#039;Settings&#039;&#039;&#039;&#039;&#039; öffnet sich das zweite Fenster, falls sich dieses nicht schon von alleine öffnen sollte. Nach den Schließen der Fenster über &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; ist der Projekt Dialog beendet und ein neues Projekt steht zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_5_1.png|Debug Eigenschaften 1. Fenster]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_5_2.png|Debug Eigenschaften 2. Fenster]]&lt;br /&gt;
&lt;br /&gt;
===2. CMSIS-Library und Startup-Code hinzufügen===&lt;br /&gt;
Wenn man sich, nachdem man ein neues Projekt in der IDE erstellt hat, die bereits vorhandenen Dateien im Projekt ansieht, stellt man fest, das bereits ein Ordner &#039;&#039;&#039;&#039;&#039;cmsis&#039;&#039;&#039;&#039;&#039; existiert, der einige wichtige Include-Dateien der CMSIS-Library enthält. Allerdings sind das wirklich nur die wichtigsten Include-Dateien der CMSIS-Library und dazu noch, die aus einer älternen Version. Ich ziehe es deshalb vor die &amp;quot;Mini-CMSIS-Libraray&amp;quot; und die &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c/.h&#039;&#039;&#039;&#039;&#039; Dateien des Projektes durch aktuellere Versionen zu ersetzen. So ist später auch die Integration  von anderen Libraries, wie z.B. der CMSIS-DSP-Libarary einfacher.  &lt;br /&gt;
&lt;br /&gt;
Zunächst gehen man in das Projekt-Verzeichnis und löscht:&lt;br /&gt;
*Den Ordner &#039;&#039;&#039;&#039;&#039;cmsis&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Alle Dateien im Include Verzeichnis &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; im &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner&lt;br /&gt;
&lt;br /&gt;
Außerdem entfernt man auch alle gelöschten Dateien in der IDE aus dem Projekt mit &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Rechts Klick -&amp;gt; Remove file from project&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Es sollte folgende Verzeichnis Struktur überbleiben:&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_6.png|Überbleibende Dateien]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Jetzt müssen die gelöschten Dateien durch die aktuelleren ersetzt werden.&lt;br /&gt;
&lt;br /&gt;
*Dazu kopieren man den gesamten Ordner &#039;&#039;&#039;&#039;&#039;CMSIS&#039;&#039;&#039;&#039;&#039; aus dem CMSIS Download in das Projekt Verzeichnis.&lt;br /&gt;
&lt;br /&gt;
*Aus dem Standard-Peripheral-Library Download kopiert man von &#039;&#039;&#039;&#039;&#039;Libraries\CMSIS\Device\ST\STM32F4xx\Include&#039;&#039;&#039;&#039;&#039; alle Dateien in den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projekt Verzeichnisses&lt;br /&gt;
&lt;br /&gt;
*Aus der Standard-Peripheral-Library kopieren man ebenfalls von &#039;&#039;&#039;&#039;&#039;Libraries\CMSIS\Device\ST\STM32F4xx\Source\Templates&#039;&#039;&#039;&#039;&#039; die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; in den &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner des Projekts&lt;br /&gt;
&lt;br /&gt;
Anschließend müssen die neuen Dateien in der IDE dem Projekt hinzugefügt werden. Dazu benutzt man &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Rechts Klick -&amp;gt; Add files&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
*Aus dem &#039;&#039;&#039;&#039;&#039;CMSIS&#039;&#039;&#039;&#039;&#039; Ordner im Projekt Verzeichnis werden aus den Unterorder &#039;&#039;&#039;&#039;&#039;Include&#039;&#039;&#039;&#039;&#039; folgende Dateien dem Projekt hinzugefügt:&lt;br /&gt;
**arm_common_tables.h&lt;br /&gt;
**arm_const_structs.h&lt;br /&gt;
**arm_math.h&lt;br /&gt;
**core_cm4.h&lt;br /&gt;
**core_cm4_simd.h&lt;br /&gt;
**core_cmFunc.h&lt;br /&gt;
**core_cmInstr.h&lt;br /&gt;
*Alle Dateien aus den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projektes&lt;br /&gt;
*Die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; aus dem &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner&lt;br /&gt;
&lt;br /&gt;
So sollte die Struktur dann aussehen:&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_7.png|Anwenungs-Grundgerüst]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Da einige Dateien der Libraries später bearbeitet werden müssen und Schreibgeschützt sind, weise ich hier schonmal darauf hin, das der Schreibschutz in der IDE über &#039;&#039;&#039;&#039;&#039;Rechts Klick auf die Datei -&amp;gt; Properties -&amp;gt; Häkchen bei &amp;quot;File is read only&amp;quot; entfernen&#039;&#039;&#039;&#039;&#039; entfert werden kann.&lt;br /&gt;
&lt;br /&gt;
Damit die IDE die Header-Dateien der CMSIS Library auch finden kann, weil diese ja nicht im standard Include Ordner &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; liegen, muss unter &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Build Options -&amp;gt; Search Directories&#039;&#039;&#039;&#039;&#039; der Pfad &#039;&#039;&#039;&#039;&#039;CMSIS\Include&#039;&#039;&#039;&#039;&#039; hinzugefügt werden.&lt;br /&gt;
&lt;br /&gt;
Compiliert man jetzt das Projekt mit &#039;&#039;&#039;&#039;&#039;F7&#039;&#039;&#039;&#039;&#039; gibt es ein paar Fehler Meldungen, weil keine Controller-Reihe ausgewählt wurde. Ebenfalls unter &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Build Options -&amp;gt; Compiler Settings -&amp;gt; #defines&#039;&#039;&#039;&#039;&#039; wird der Define &#039;&#039;&#039;&#039;&#039;STM32F40_41xxx&#039;&#039;&#039;&#039;&#039; hinzugefügt.&lt;br /&gt;
&lt;br /&gt;
Beim erneuten Compilieren sollten sich nun keine neuen Fehler ergeben.&lt;br /&gt;
&lt;br /&gt;
===Das erste Programm===&lt;br /&gt;
Nachdem ein grundsätzliches &amp;quot;Gerüst&amp;quot; fertig ist, kann man den ersten Code schreiben.&lt;br /&gt;
main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC-&amp;gt;AHB1ENR |= RCC_AHB1ENR_GPIODEN;    //Takt für GPIO aktivieren&lt;br /&gt;
    GPIOD-&amp;gt;MODER |= GPIO_MODER_MODER15_0;   //GPIOD Pin15 als Ausgang&lt;br /&gt;
    GPIOD-&amp;gt;BSRRL |= GPIO_BSRR_BS_15;        //GPIOD Pin15 auf High ziehen&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039; wird dann der Debugger gestartet. Hat der Debugger das Projekt erfolgreich übertragen kann die Ausführung mit &#039;&#039;&#039;&#039;&#039;F5&#039;&#039;&#039;&#039;&#039; begonnen werden.&lt;br /&gt;
&lt;br /&gt;
==Libraries einbinden/verwenden==&lt;br /&gt;
===Einbinden der Standard-Peripheral-Library===&lt;br /&gt;
Um nicht immer die einzelnen Register, wie im ersten &amp;quot;bare-metal&amp;quot; Beispiel, aus dem Reference-Manual zu suchen und zu beschreiben, gibt es von ST die Standard Peripheral Library, die diese Aufgaben übernimmt und mit der sich die &amp;quot;normale/grundlegende&amp;quot; (Alles außer USB und Ethernet) Peripherie recht einfach steuern lässt. Um die Library zu verwenden erzeugt man wie oben beschrieben ein neues Grundgerüst und kopiert als erstes den Ordner &#039;&#039;&#039;&#039;&#039;Libraries\STM32F4xx_StdPeriph_Driver&#039;&#039;&#039;&#039;&#039; aus dem Standard-Peripheral-Library Download in das Projekt-Verzeichnis. Außerdem muss man die Datei &#039;&#039;&#039;&#039;&#039;Project\STM32F4xx_StdPeriph_Templates\stm32f4xx_conf.h&#039;&#039;&#039;&#039;&#039; ebenfalls aus dem Standard-Peripheral-Library Download in den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projektes kopieren. In der IDE fügt man den Include-Path &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\inc&#039;&#039;&#039;&#039;&#039; hinzufügen, wie bei der CMSIS-Library (s.o.).&lt;br /&gt;
Außerdem muss noch &#039;&#039;&#039;&#039;&#039;USE_STDPERIPH_DRIVER&#039;&#039;&#039;&#039;&#039; als Define in der IDE hinzugefügt werden (s.o.).&lt;br /&gt;
Danach fügt man die Source- und Include-Dateien aus dem Ordner &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\inc&#039;&#039;&#039;&#039;&#039; und &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\src&#039;&#039;&#039;&#039;&#039; dem Project mit &#039;&#039;&#039;&#039;&#039;&amp;lt;Project Name&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Add files&#039;&#039;&#039;&#039;&#039; hinzu, allerdings nur die, für welche auch der Controller die entsprechende Peripherie besitzt. Beim STM32F4-Discovery Board / STM32F407VG Controller dürfen also nicht folgende Dateien nicht mit hinzugefügt werden, weil diese Peripherie nur bei anderen Controller vorhanden ist:&lt;br /&gt;
&lt;br /&gt;
*stm32f4xx_dma2d.c/.h&lt;br /&gt;
*stm32f4xx_fmc.c/.h&lt;br /&gt;
*stm32f4xx_ltdc.c/.h&lt;br /&gt;
*stm32f4xx_sai.c/.h&lt;br /&gt;
&lt;br /&gt;
Daraus resultiert folgende Struktur:&lt;br /&gt;
&lt;br /&gt;
[[Datei:stdperiphlib_2.png|Header-Struktur]] [[Datei:stdperiphlib_1.png|Source-Struktur]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Anschließen kann die Standard-Peripheral-Library benutz werden.&lt;br /&gt;
main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);&lt;br /&gt;
&lt;br /&gt;
    GPIO_InitTypeDef GPIOD_InitStructure;&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Mode = GPIO_Mode_OUT;     //Als Ausgang&lt;br /&gt;
    GPIOD_InitStructure.GPIO_OType = GPIO_OType_PP;    //Push-Pull Betrieb&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Pin = GPIO_Pin_15;        //Pin 15 (STM32F4-Discovery: Blaue LED)&lt;br /&gt;
    GPIOD_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;  //Kein Pull-Up oder Pull-Down Widerstand aktiviert&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Speed = GPIO_Speed_25MHz; //25MHz Update-Rate&lt;br /&gt;
    GPIO_Init(GPIOD, &amp;amp;GPIOD_InitStructure);&lt;br /&gt;
&lt;br /&gt;
    GPIO_SetBits(GPIOD, GPIO_Pin_15);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Einbinden der DSP-Library===&lt;br /&gt;
STM32F3 / STM32F4 Microcontroller haben neben der FPU noch einen Digital-Signal-Processor (DSP). Die DSP dient hauptsächlich dazu, viele Daten schnell zu verarbeiten (z.B. Video- oder Audiosignal). Der CMSIS-Download beinhaltet dazu neben der eigentlichen CMSIS-Library auch noch eine DSP-Library. Diese Library stellt sowohl einfache, mathematische Funktionen wie addieren, multiplizieren usw. als auch komplexe Funktionen, wie z.B  einen IIR-Filter, zur Verfügung. Die DSP-Library ist weiter aufgeteilt in kleinere Module, wie z.B. BasicMathFunctions, FilteringFunctions usw. (siehe &#039;&#039;&#039;&#039;&#039;CMSIS\DSP-Library\Source&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
Um die DSP-Library zu verwenden müssen nur die Source-Files des benötigten Moduls einbinden.&lt;br /&gt;
(&#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Add files...&#039;&#039;&#039;&#039;&#039;). Außerdem muss in der &#039;&#039;&#039;&#039;&#039;main.c&#039;&#039;&#039;&#039;&#039; der Include &#039;&#039;&#039;&#039;&#039;arm_math.h&#039;&#039;&#039;&#039;&#039; eingebunden werden. Aus irgendeinem Grund gibt es dann jedoch die Warnung: &amp;quot;Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)&amp;quot;. Ich hab noch nicht rausgefunden, wieso diese Warnung auftaucht. Die Warnung verschwindet, wenn man in der &#039;&#039;&#039;&#039;&#039;Build options...&#039;&#039;&#039;&#039;&#039; das Define &#039;&#039;&#039;&#039;&#039;__FPU_PRESENT&#039;&#039;&#039;&#039;&#039; hinzufügt (Ich weiß selber das das keine schöne Lösung ist, eine andere hab ich jedoch noch nicht gefunden). Jetzt kann die DSP-Library verwedet werden. Das Beispiel multipliziert zwei Buffer miteinander. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
#include &amp;quot;arm_math.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    float32_t x[1024];&lt;br /&gt;
    float32_t y[1024];&lt;br /&gt;
    float32_t z[1024];&lt;br /&gt;
&lt;br /&gt;
    for(uint16_t i = 0; i &amp;lt; 1024; i++)&lt;br /&gt;
    {&lt;br /&gt;
        x[i] = i;&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for(uint16_t i = 0; i &amp;lt; 1024; i++)&lt;br /&gt;
    {&lt;br /&gt;
        y[i] = PI;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    arm_mult_f32(x, y, z, 1024);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Startup-Code, Linker-Script, Takt, FPU usw.==&lt;br /&gt;
===Startup-Code===&lt;br /&gt;
Em::Blocks fügt standardmäßig einen Startup-Code mit in das Projekt ein. Die wichtigsten Dinge die darin erledigt werden sind folgende:&lt;br /&gt;
&lt;br /&gt;
*Stack und Heap wird angelgt&lt;br /&gt;
*Die Vector-Table wird angelegt&lt;br /&gt;
*Ein Default Reset-Handler wird implementiert, dieser erledigt folgende aufgaben:&lt;br /&gt;
**Kopieren der definierten Daten aus dem Flash in den SRAM&lt;br /&gt;
**&#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; wird aufgerfen, wenn &#039;&#039;&#039;&#039;&#039;__NO_SYSTEM_INIT&#039;&#039;&#039;&#039;&#039; nicht definiert ist&lt;br /&gt;
**Sprung in die &#039;&#039;&#039;&#039;&#039;main()&#039;&#039;&#039;&#039;&#039; Funktion&lt;br /&gt;
*Allen anderen Interrupt-Handler wird eine Default-Funktion &#039;&#039;&#039;&#039;&#039;def_irq_handler&#039;&#039;&#039;&#039;&#039; mit einer &#039;&#039;&#039;&#039;&#039;while(1)&#039;&#039;&#039;&#039;&#039;-Schleife zugewiesen, falls kein anderer Interrupt-Handler existiert.&lt;br /&gt;
&lt;br /&gt;
Normalerweise muss am Startup-Code nichts verändert werden.&lt;br /&gt;
&lt;br /&gt;
===Linker-Script===&lt;br /&gt;
Em::Blocks stellt zwei fertige Linker-Scripts bereit, eins für die Ausführung des Programmes aus dem Flash (&#039;&#039;&#039;&#039;&#039;*_flash.ld&#039;&#039;&#039;&#039;&#039;), das andere für die Ausführung aus dem SRAM (&#039;&#039;&#039;&#039;&#039;*_sram.ld&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Normalerweise muss auch hier nichts geändert werden, es sei den Daten sollen in bestimmten Adressbereichen abgelegt werden (z.B. im Core-Coupled RAM), was ich später noch zum Tutorial hinzufüge.&lt;br /&gt;
&lt;br /&gt;
===Der Takt===&lt;br /&gt;
Jeder Controller oder Prozessor braucht einen Takt, indem er die einzelnen Maschinen-Befehle abarbeiten kann.&lt;br /&gt;
Bei den STM32 Mikrocontrollern kann dieser Takt aus verschiedenen Quellen kommen:&lt;br /&gt;
&lt;br /&gt;
1. High Speed Internal Oszillator (HSI)&lt;br /&gt;
&lt;br /&gt;
2. High Speed External Oszillator (HSE)&lt;br /&gt;
&lt;br /&gt;
3. Low Speed Internal Oszillator (LSI)&lt;br /&gt;
&lt;br /&gt;
4. Low Speed External Oszillator (LSE)&lt;br /&gt;
&lt;br /&gt;
5. Phase-Locked Loop (PLL) (generiert den Takt aus den ersten vier Taktquellen durch Teiler und Faktoren)&lt;br /&gt;
&lt;br /&gt;
Nach einem Reset wird der Controller aus der HSI Taktquelle versorgt (16MHz beim STM32F407VG). Um die voll Performance des Controllers zu erreichen muss die PLL verwendet werden, welche den Takt durch geschickte Teiler und Faktoren vervielfältigt, sodass am Ende der Controller mit der maximalen Taktfrequenz läuft. Die notwendige Initialisierung der PLL findet in der Funktion &#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; statt. Die PLL erzeugt zunächst einen Basistakt:&lt;br /&gt;
&lt;br /&gt;
PLL_VCO = (F_HSE / PLL_M) * PLL_N&lt;br /&gt;
&lt;br /&gt;
Aus diesem Takt wird dann der Takt für den Controller-Kern abgeleitet:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = PLL_VCO / PLL_P&lt;br /&gt;
&lt;br /&gt;
Und der Takt für SDIO / USB / RNG (48MHz):&lt;br /&gt;
&lt;br /&gt;
48MHz = PLL_VCO / PLL_Q&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Durch weiter Teiler werden, die Takte für die einzelnen Busse erzeugt, da diese nicht alle beliebig schnell betrieben werden dürfen.&lt;br /&gt;
&lt;br /&gt;
Genaue Angaben findet man zu dem jeweiligen Clock-System des Controllers im Reference Manual.&lt;br /&gt;
&lt;br /&gt;
Ein Blick in den &amp;quot;Kommentar-Header&amp;quot; verrät, dass von einem externen (HSE) Oszillator von 25MHz ausgegangen wird, der die PLL versorgen soll.&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((25MHz / PLL_M(25)) * PLL_N(336)) / PLL_P(2) = 168MHz&lt;br /&gt;
&lt;br /&gt;
Allerdings stimmt diese Rechnung natürlich nur, wenn wirklich ein 25MHz Quarz am Controller angeschlossen ist. Auf dem STM32F4-Discovery Board befindet sich aber nur ein 8MHz Quarz. Demnach gilt:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((8MHz / PLL_M(25)) * PLL_N(336)) / PLL_P(2) = 53.76MHz&lt;br /&gt;
&lt;br /&gt;
Der Controller läuft also nur mit 53.76MHz, wenn wie ober beschrieben ein Projekt erstellt wird. Allerdings kann dieses Problem durch ändern von den betroffen Defines behoben werden:&lt;br /&gt;
 &lt;br /&gt;
*Dazu geht man in die &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; Datei und passt zur Vollständigkeit erstmal die zum Controller passende Tabelle im &amp;quot;Kommentar-Header&amp;quot; an (Z.57f):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      HSE Frequency(Hz)                      | 8000000&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      PLL_M                                  | 8&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Danach passt man den PPL_M Define (Z.254) an:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/************************* PLL Parameters *************************************/&lt;br /&gt;
/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */&lt;br /&gt;
#define PLL_M      8&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Außerdem muss man den HSE_VALUE Define in der &#039;&#039;&#039;&#039;&#039;inc/stm32f4xx.h&#039;&#039;&#039;&#039;&#039; angepasst werden (Z.122):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#if !defined  (HSE_VALUE)&lt;br /&gt;
  #define HSE_VALUE    ((uint32_t)8000000) /*!&amp;lt; Value of the External oscillator in Hz */&lt;br /&gt;
&lt;br /&gt;
#endif /* HSE_VALUE */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine neue Berechnung zeigt:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((8MHz / PLL_M(8)) * PLL_N(336)) / PLL_P(2) = 168MHz&lt;br /&gt;
&lt;br /&gt;
Jetzt läuft der Controller mit maximaler Geschwindigkeit.&lt;br /&gt;
&lt;br /&gt;
Die Theorie wird durch folgendes Programm verifiziert. Der geviertelte System-Takt SYSCLK wir am Pin PC9 ausgegeben. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);&lt;br /&gt;
&lt;br /&gt;
    GPIO_InitTypeDef GPIOC_InitStructure;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Mode = GPIO_Mode_AF;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_OType = GPIO_OType_PP;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Pin = GPIO_Pin_9;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;&lt;br /&gt;
    GPIO_Init(GPIOC, &amp;amp;GPIOC_InitStructure);&lt;br /&gt;
&lt;br /&gt;
    RCC_MCO2Config(RCC_MCO2Source_SYSCLK, RCC_MCO2Div_4);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Die FPU===&lt;br /&gt;
====Allgemeines====&lt;br /&gt;
Damit die FPU richtig verwendet wird, müssen normalerweise zwei Bedingungen erfüllt sein:&lt;br /&gt;
&lt;br /&gt;
1. Der Controller muss in der Initialisierung-Funktion &#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; in &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; die FPU Hardware-seitig aktivieren&lt;br /&gt;
&lt;br /&gt;
2. Damit die FPU auch was zu tuen bekommt, müssen vom Compiler FPU-Instructions erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
Die Em::Blocks IDE verwendet standardmäßig die FPU, wenn eine Vorhanden ist. Hier wird die FPU Hardware-seitig aktiviert (&#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; Z.341):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* FPU settings ------------------------------------------------------------*/&lt;br /&gt;
  #if (__FPU_PRESENT == 1) &amp;amp;&amp;amp; (__FPU_USED == 1)&lt;br /&gt;
    SCB-&amp;gt;CPACR |= ((3UL &amp;lt;&amp;lt; 10*2)|(3UL &amp;lt;&amp;lt; 11*2));  /* set CP10 and CP11 Full Access */&lt;br /&gt;
  #endif&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
__FPU_PRESENT wird in der &#039;&#039;&#039;&#039;&#039;stm32f4xx.h&#039;&#039;&#039;&#039;&#039; definiert.&lt;br /&gt;
__FPU_USED wird von der IDE übernommen (siehe Build-Log): &#039;&#039;&#039;&#039;&#039;-D__FPU_USED&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Außerdem wird der Compiler von der IDE standardmäßig mit dem Argument &#039;&#039;&#039;&#039;&#039;-mfloat-abi=hard&#039;&#039;&#039;&#039;&#039; aufgerufen, wodurch FPU-Instructions erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
====FPU abschalten====&lt;br /&gt;
Um die FPU ab zu schalten (Mir würde jetzt nur Strom sparen als Grund einfallen) geht man wie folgt vor:&lt;br /&gt;
&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick Build options -&amp;gt; Device -&amp;gt; Policy&#039;&#039;&#039;&#039;&#039; wählt man &#039;&#039;&#039;&#039;&#039;Use target settings&#039;&#039;&#039;&#039;&#039; und über nimmt die Einstellungen, die vorher dort eingetragen waren, allerdings lässt man das Feld &#039;&#039;&#039;&#039;&#039;FP-hardware&#039;&#039;&#039;&#039;&#039; frei.&lt;br /&gt;
&lt;br /&gt;
[[Datei:fpu_1.png|FPU Abschalten Schritt 1]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;Compiler Settings -&amp;gt; Policy&#039;&#039;&#039;&#039;&#039; wählt man dann &#039;&#039;&#039;&#039;&#039;Use target options only&#039;&#039;&#039;&#039;&#039;. Dann kann man unter &#039;&#039;&#039;&#039;&#039;Categories&#039;&#039;&#039;&#039;&#039; die Option &#039;&#039;&#039;&#039;&#039;ARM FPU architecture&#039;&#039;&#039;&#039;&#039; auswählen. Dort stehen dann drei Möglichkeiten für die FPU zur Verfügung:&lt;br /&gt;
&lt;br /&gt;
1. Software-FPU-Library für Gleitkomma-Berechnung verwenden - Keine FPU-Instructions werden generiert (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=soft&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
2. Eine Mischung aus Software- und Hardware-FPU wird verwendet (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=softfp&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
3. Hardware-FPU wird für Gleitkomma-Berechnungen verwendet (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=hard&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
[[Datei:fpu_2.png|FPU Abschalten Schritt 2]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Um die FPU ab zu schalten wählt man natürlich die erste Möglichkeit.&lt;br /&gt;
Bei der 2. und 3. Möglichkeit fügt die IDE auch den Define &#039;&#039;&#039;&#039;&#039;__FPU_USED&#039;&#039;&#039;&#039;&#039; hinzu. Bei Der ersten Möglichkeit nicht. Der Code muss also nicht verändert / auskommentiert werden.&lt;br /&gt;
&lt;br /&gt;
Um die FPU wieder zu aktivieren müssen alle Schritte wieder rückgängig gemacht werden.&lt;br /&gt;
&lt;br /&gt;
Am besten ist es einfach mal alle Möglichkeiten im Einzelschritt durch zu probieren. Dann stellt man schnell fest, ob die FPU aktiviert wir oder nicht. Ein Blick in den erweiterten &#039;&#039;&#039;&#039;&#039;Build-Log&#039;&#039;&#039;&#039;&#039; gibt auch schnell Aufschluss darüber, wie der Compiler aufgerufen wird (siehe Kapitel [http://www.mikrocontroller.net/articles/STM32_-_Einstieg_mit_Em::Blocks#Compilieren Compilieren]).&lt;br /&gt;
&lt;br /&gt;
====Test Programm für die FPU====&lt;br /&gt;
Hier ein kleines Testprogramm, dass misst wie viele Taktzyklen für eine Gleitkomma-Multiplikation gebraucht werden. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define CORE_SysTickEn()    (*((u32*)0xE0001000)) = 0x40000001&lt;br /&gt;
#define CORE_SysTickDis()   (*((u32*)0xE0001000)) = 0x40000000&lt;br /&gt;
#define CORE_GetSysTick()   (*((u32*)0xE0001004))&lt;br /&gt;
&lt;br /&gt;
uint32_t t1, t2, dt;&lt;br /&gt;
float x, y, z;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    x = 53.64f;&lt;br /&gt;
    y = 0.27f;&lt;br /&gt;
&lt;br /&gt;
    CORE_SysTickEn();&lt;br /&gt;
    t1 = CORE_GetSysTick();&lt;br /&gt;
&lt;br /&gt;
    z = x * y;&lt;br /&gt;
&lt;br /&gt;
    t2 = CORE_GetSysTick();&lt;br /&gt;
    CORE_SysTickDis();&lt;br /&gt;
&lt;br /&gt;
    dt = (t2 - t1) - 9; //9 Takt-Zyklen werden für die Messung gebraucht &lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Booten aus dem SRAM==&lt;br /&gt;
STM32 Controller haben die Möglichkeit Code aus dem Flash als auch aus dem SRAM auszuführen. Um eine Anwenung per Debugger in des SRAM zu laden sind nur wenige Schritte erforderlich:&lt;br /&gt;
&lt;br /&gt;
*Um das Linkerscript für den SRAM zu verwenden geht man zu: &#039;&#039;&#039;&#039;&#039;Build options... -&amp;gt; Device&#039;&#039;&#039;&#039;&#039; dort wählt man unter &#039;&#039;&#039;&#039;&#039;Policy&#039;&#039;&#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;Use target settings&#039;&#039;&#039;&#039;&#039; aus und übernimmt die vorherigen Einstellungen, nur unter &#039;&#039;&#039;&#039;&#039;Linker script*&#039;&#039;&#039;&#039;&#039; gibt man &#039;&#039;&#039;&#039;&#039;.\stm32f407vg_sram.ld&#039;&#039;&#039;&#039;&#039; an&lt;br /&gt;
&lt;br /&gt;
*Dann muss man noch unter &#039;&#039;&#039;&#039;&#039;Debug -&amp;gt; Interfaces -&amp;gt; Settings&#039;&#039;&#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;Vector table start&#039;&#039;&#039;&#039;&#039; auf 0x20000000 ändern und &#039;&#039;&#039;&#039;&#039;Execute from RAM&#039;&#039;&#039;&#039;&#039; auswählen.&lt;br /&gt;
&lt;br /&gt;
Anschließend kann man die Anwendung ganz normal debuggen. Nach einem Reset muss die Anwenung erneut mit dem Debugger gestartet werden.&lt;br /&gt;
&lt;br /&gt;
=Fortsetzung folgt..=&lt;br /&gt;
Kritik, Wünsche usw. sind gerne erwünscht, am besten hier in den Thread posten: [http://www.mikrocontroller.net/topic/323750 Neues STM32 Tutorial]&lt;br /&gt;
&lt;br /&gt;
[[Category:ARM]]&lt;br /&gt;
[[Category:STM32]]&lt;/div&gt;</summary>
		<author><name>Avrprogger</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=STM32_-_Einstieg_mit_Em::Blocks&amp;diff=81542</id>
		<title>STM32 - Einstieg mit Em::Blocks</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=STM32_-_Einstieg_mit_Em::Blocks&amp;diff=81542"/>
		<updated>2014-02-11T16:40:07Z</updated>

		<summary type="html">&lt;p&gt;Avrprogger: fgh&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In diesem Tutorial werde ich versuchen, möglichst einfach, die ersten Schritte zur Entwicklung von STM32 Anwenungen mit der Em::Blocks IDE zu erklären. Hier soll nicht so stark auf die einzelnen Peripherie-Module der Controller eingegangen werden, sondern mehr auf die IDE und die verschieden Libraries, wie die CMSIS Library, die DSP-Library, die Standard-Peripheral-Library, die USB-Library und vllt. über Ethernet. Ich denke ein Kapitel zu FreeRTOS wird es auch geben. Auserdem steht im Vordergrund Sachen wie z.B. booten aus dem SRAM, In-Application-Programming, FPU, Core-Coupled-RAM usw. Mal sehn wie weit ich komme ;)&lt;br /&gt;
&lt;br /&gt;
==Die Entwicklungsumgebung==&lt;br /&gt;
===Hardware===&lt;br /&gt;
Zum testen der Anwendungen, benutze ich das STM32F4-Discovery Board, welches einen Debugger, Peripherie und natürlich einen STM32 Controller (STM32F407VGT6) enthält. Deshalb sind alle Beispiele hier für den STM32F407VG Controller ausgelegt, können aber meisten 1:1 auf andere Controller portiert werden. Ich werde auch möglichsts keine STM32F4-Discovery Board spezifischen Libraries verwenden, damit der Portierungs-Vorgang möglichsts einfach bleibt.&lt;br /&gt;
&lt;br /&gt;
===Software===&lt;br /&gt;
In diesem Tutorial verwende ich [http://www.emblocks.org/ Em::Blocks] als IDE. Em::Blocks ist eine kostenlose, uneingeschränkte IDE, die alle STM32 Mikrcontroller unterstützt und sehr einfach zu bedienen ist.&lt;br /&gt;
nach dem Download kann die IDE per Dialog, sehr einfach, installiert werden. Als Compiler beinhaltet Em::Blocks den &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
Die IDE unterstützt zurzeit den ST-Link, den J-Link und es gibt eine Generic-Vorlage, durch welche andere Debugger konfiguriert werden können.&lt;br /&gt;
&lt;br /&gt;
Außerdem muss noch der passende Treiber für den Debugger installiert werden. Verwendet man ein Discovery-Board muss der [http://www.st.com/web/catalog/tools/FM146/CL1984/SC724/SS1677/PF251168 ST-Link/V2]-Treiber heruntergeladen und installiert werden. (Die Installation muss evtl. als Administrator ausgeführt werden, da sonst die Installation unvollständig wird.) Nach der Installation des Treibers kann man den Debugger über die entsprechende USB Schnittstelle an den PC anschließen und es sollte die Meldung von Windows kommen, dass der richtige Treiber gefunden wurde.&lt;br /&gt;
&lt;br /&gt;
===Libraries===&lt;br /&gt;
Zum programmieren benötigt man noch die [http://www.arm.com/products/processors/cortex-m/cortex-microcontroller-software-interface-standard.php CMSIS] und die Standard-Peripheral-Library (z.B. für die F4 Controller [http://www.st.com/stonline/stappl/productcatalog/app?page=partNumberSearchPage&amp;amp;levelid=SS1577&amp;amp;parentid=1743&amp;amp;resourcetype=SW Standard-Peripheral-Library-F4]), die man am besten in einen Ordner (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\STM32&#039;&#039;&#039;&#039;&#039;) entpackt&lt;br /&gt;
&lt;br /&gt;
==Basis-Wissen zur IDE==&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von Dateien zum Projekt===&lt;br /&gt;
Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf &amp;lt;ProjektName&amp;gt; -&amp;gt; Add files...&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Enfernen von Dateien aus dem Projekt===&lt;br /&gt;
Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf die Datei / mehrere Dateien auswählen -&amp;gt; Remove file from project&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
Die Dateien werden lediglich aus dem Projekt entfernt und nicht von der Festplatte gelöscht.&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von Include-Pfaden===&lt;br /&gt;
Sofern die Include-Datei(en) nicht im standard Include-Ordner &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; des Projektes liegen, muss man den Pfad zum Projekt hinzufügen, damit der Compiler die Include-Dateien später auch finden kann. Man geht wie folgt vor: Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf &amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; Search Directories -&amp;gt; Add&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von globalen Defines zum Build===&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; #defines&#039;&#039;&#039;&#039;&#039; können globale Defines hinzugefügt werden.&lt;br /&gt;
&lt;br /&gt;
===Compilieren===&lt;br /&gt;
Entweder über das &#039;&#039;&#039;&#039;&#039;Build&#039;&#039;&#039;&#039;&#039; Menü oder über &#039;&#039;&#039;&#039;&#039;F7&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Um eine genau Ausgabe des Compiler-Aufrufes mit allen Argumenten zu bekommen, geht man im &#039;&#039;&#039;&#039;&#039;Settings&#039;&#039;&#039;&#039;&#039; Menü auf &#039;&#039;&#039;&#039;&#039;Tools...&#039;&#039;&#039;&#039;&#039; und dann auf &#039;&#039;&#039;&#039;&#039;Toolchain executables&#039;&#039;&#039;&#039;&#039;. Ganz unten, unter &#039;&#039;&#039;&#039;&#039;Logging&#039;&#039;&#039;&#039;&#039; kann man dann &#039;&#039;&#039;&#039;&#039;Full command line&#039;&#039;&#039;&#039;&#039; auswählen.&lt;br /&gt;
&lt;br /&gt;
====Compiler Optionen====&lt;br /&gt;
=====Optimierung=====&lt;br /&gt;
Standardmäßig verwendet Em::Blocks keine Optimierung. Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; Categories: Optimization&#039;&#039;&#039;&#039;&#039; kann zwischen verschieden Optimierungen ausgewählt werden.&lt;br /&gt;
&lt;br /&gt;
=====Verschiedene C-Standards=====&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; Categories: Language standard&#039;&#039;&#039;&#039;&#039; kann man zwischen verschieden C-Standard auswählen, wie z.B, C99.&lt;br /&gt;
(Mit C99 können auch die Lauf-Variable in der for-Schleife deklariert werden: for(int i;..))&lt;br /&gt;
&lt;br /&gt;
===Debuggen===&lt;br /&gt;
*Als erstes den Debugger starten über das &#039;&#039;&#039;&#039;&#039;Debug&#039;&#039;&#039;&#039;&#039; Menü und &#039;&#039;&#039;&#039;&#039;Start/stop Debug Session&#039;&#039;&#039;&#039;&#039; oder über &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
*Danach läuft die Anwendung auf dem Controller und warten im &#039;&#039;&#039;&#039;&#039;Reset_Handler&#039;&#039;&#039;&#039;&#039; auf Einzelschritt- bzw. Run- Befehle (&#039;&#039;&#039;&#039;&#039;F5, F10, F11&#039;&#039;&#039;&#039;&#039; usw..(siehe &#039;&#039;&#039;&#039;&#039;Debug-Menü&#039;&#039;&#039;&#039;&#039; für alle Möglichkeiten))&lt;br /&gt;
&lt;br /&gt;
*Mit &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039; wird die Debug-Session auch wieder beendet&lt;br /&gt;
&lt;br /&gt;
*Unter &#039;&#039;&#039;&#039;&#039;Debug -&amp;gt; Interfaces -&amp;gt; Target settings&#039;&#039;&#039;&#039;&#039; können Eigenschaften, wie z.B &#039;&#039;&#039;&#039;&#039;Run to main()&#039;&#039;&#039;&#039;&#039; aktiviert werden.&lt;br /&gt;
&lt;br /&gt;
===Projekt als Template abspeichern===&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;File -&amp;gt; Save project as template...&#039;&#039;&#039;&#039;&#039;. Das Template erscheint dann im Projekt-Dialog unter &#039;&#039;&#039;&#039;&#039;User templates&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Das erste Projekt erstellen==&lt;br /&gt;
Hier erkläre ich, wie man am Besten (aus meiner Sicht), ein neues Projekt von Grund auf erstellt, sodass man hinterher, den Controller-Kern über die CMSIS-Library und die Peripherie über die Register steuern kann.&lt;br /&gt;
&lt;br /&gt;
===1. Projekt mit der IDE erstellen===&lt;br /&gt;
Nach der Installation der oben beschriebenen Komponenten erstellt man am besten ein Verzeichnis (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\EmBlocks&#039;&#039;&#039;&#039;&#039;), indem später alle Projekte gespeichert werden. Für Libraries kann man auch noch ein Verzeichnis (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\STM32&#039;&#039;&#039;&#039;&#039;) erstellen, wo alle Libraries gespeichert werden, die man für die Projekt brauchen.&lt;br /&gt;
&lt;br /&gt;
Als nächstes starten man EmBlocks. Bei dem ersten Start öffnet sich ein Fenster, wo verschiedene Compiler angezeigt werden, die Em::Blocks findet. Dort wählt man den &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039; aus und klickt &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039;. Nun sollte sich das Hauptfenster von Em::Blocks öffnen. Über &#039;&#039;&#039;&#039;&#039;Create a new Project&#039;&#039;&#039;&#039;&#039; oder &#039;&#039;&#039;&#039;&#039;File -&amp;gt; New -&amp;gt; Project&#039;&#039;&#039;&#039;&#039; ruft man den Projekt-Dialog auf und kann ein neues Projekt erzeugen.&lt;br /&gt;
&lt;br /&gt;
Auf der Ersten Seite wählen man den &#039;&#039;&#039;&#039;&#039;STmicro-ARM&#039;&#039;&#039;&#039;&#039; Projekt-Typ aus.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_1.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auf der nächsten Seite wird man darauf hingewiesen, dass das der entsprechende Projekt-Typ-Dialog ausgeführt wird. Hier kann man ein Häkchen bei &#039;&#039;&#039;&#039;&#039;Skip this page next time&#039;&#039;&#039;&#039;&#039; setzen und auf &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; klicken.&lt;br /&gt;
&lt;br /&gt;
Im nächsten Schritt wählen man das zuvor erstellt Verzeichnis unter &#039;&#039;&#039;&#039;&#039;Folder to create Project in&#039;&#039;&#039;&#039;&#039; aus, indem später alle Projekt gespeichert werden. Außerdem geben wir dem Projekt einen Namen (z.B. &#039;&#039;&#039;&#039;&#039;FirstProject&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_2.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danach muss man einen Compiler auswählen und bestimmen, welche Projekt-Konfigurationen erszeugt werden sollen. Unter &#039;&#039;&#039;&#039;&#039;Compiler&#039;&#039;&#039;&#039;&#039; wählt man &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039; und man kann das Häkchen bei &#039;&#039;&#039;&#039;&#039;Create &amp;quot;Release&amp;quot; configuration&#039;&#039;&#039;&#039;&#039; entfernen, da diese unnötig ist, die Debug-Konfiguration sollte eig. immer ausreichen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_3.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auf den folgenden Seite wird der Controller ausgewählt. Verwendet man ein STM32F4-Discovery Board müssen folgende Dinge gewählt werden: &#039;&#039;&#039;&#039;&#039;Cortex_M4 (F3xx - F4xx) -&amp;gt; STM32F4xx (Cortex M4 with FPU) -&amp;gt; STM32F407VG&#039;&#039;&#039;&#039;&#039;. Leider sind die Auswahl Möglichkeiten nicht ganz richtig, da auch die F3 Controller einen Cortex M4 Kern und eine FPU haben (Ist aber nicht so wichtig, ist nur eine formale Sache). Außerdem entfernt man das Häkchen bei &#039;&#039;&#039;&#039;&#039;Standard Peripherals Library&#039;&#039;&#039;&#039;&#039; (Wie man die Standard-Peripheral-Library einbindet und verwendet erkläre ich später). Man kann auch das Häkchen bei &#039;&#039;&#039;&#039;&#039;Create hex file for Realease target&#039;&#039;&#039;&#039;&#039; entfernen.&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;Stack Size&#039;&#039;&#039;&#039;&#039; und &#039;&#039;&#039;&#039;&#039;Heap Size&#039;&#039;&#039;&#039;&#039; wird die Größe von Stack und Heap festgelegt. Für eine erste Anwendung kann man die Einstellungen so lassen (Stack-Size: 0x0100 =&amp;gt; 256 Byte Stack und Heap-Size: 0x0000 =&amp;gt; kein Heap). Mit &#039;&#039;&#039;&#039;&#039;Finish&#039;&#039;&#039;&#039;&#039; ist der Projekt Dialog abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_4.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danach sollten sich zwei neue Fenster öffnen, um die Debug-Eigenschaften fest zu legen.&lt;br /&gt;
Verwendet man ein Discovery Board/ST-Link müssen die Einstellungen wie auf dem Bild gewählt werden. Über den Button &#039;&#039;&#039;&#039;&#039;Settings&#039;&#039;&#039;&#039;&#039; öffnet sich das zweite Fenster, falls sich dieses nicht schon von alleine öffnen sollte. Nach den Schließen der Fenster über &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; ist der Projekt Dialog beendet und ein neues Projekt steht zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_5_1.png|Debug Eigenschaften 1. Fenster]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_5_2.png|Debug Eigenschaften 2. Fenster]]&lt;br /&gt;
&lt;br /&gt;
===2. CMSIS-Library und Startup-Code hinzufügen===&lt;br /&gt;
Wenn man sich, nachdem man ein neues Projekt in der IDE erstellt hat, die bereits vorhandenen Dateien im Projekt ansieht, stellt man fest, das bereits ein Ordner &#039;&#039;&#039;&#039;&#039;cmsis&#039;&#039;&#039;&#039;&#039; existiert, der einige wichtige Include-Dateien der CMSIS-Library enthält. Allerdings sind das wirklich nur die wichtigsten Include-Dateien der CMSIS-Library und dazu noch, die aus einer älternen Version. Ich ziehe es deshalb vor die &amp;quot;Mini-CMSIS-Libraray&amp;quot; und die &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c/.h&#039;&#039;&#039;&#039;&#039; Dateien des Projektes durch aktuellere Versionen zu ersetzen. So ist später auch die Integration  von anderen Libraries, wie z.B. der CMSIS-DSP-Libarary einfacher.  &lt;br /&gt;
&lt;br /&gt;
Zunächst gehen man in das Projekt-Verzeichnis und löscht:&lt;br /&gt;
*Den Ordner &#039;&#039;&#039;&#039;&#039;cmsis&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Alle Dateien im Include Verzeichnis &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; im &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner&lt;br /&gt;
&lt;br /&gt;
Außerdem entfernt man auch alle gelöschten Dateien in der IDE aus dem Projekt mit &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Rechts Klick -&amp;gt; Remove file from project&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Es sollte folgende Verzeichnis Struktur überbleiben:&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_6.png|Überbleibende Dateien]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Jetzt müssen die gelöschten Dateien durch die aktuelleren ersetzt werden.&lt;br /&gt;
&lt;br /&gt;
*Dazu kopieren man den gesamten Ordner &#039;&#039;&#039;&#039;&#039;CMSIS&#039;&#039;&#039;&#039;&#039; aus dem CMSIS Download in das Projekt Verzeichnis.&lt;br /&gt;
&lt;br /&gt;
*Aus dem Standard-Peripheral-Library Download kopiert man von &#039;&#039;&#039;&#039;&#039;Libraries\CMSIS\Device\ST\STM32F4xx\Include&#039;&#039;&#039;&#039;&#039; alle Dateien in den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projekt Verzeichnisses&lt;br /&gt;
&lt;br /&gt;
*Aus der Standard-Peripheral-Library kopieren man ebenfalls von &#039;&#039;&#039;&#039;&#039;Libraries\CMSIS\Device\ST\STM32F4xx\Source\Templates&#039;&#039;&#039;&#039;&#039; die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; in den &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner des Projekts&lt;br /&gt;
&lt;br /&gt;
Anschließend müssen die neuen Dateien in der IDE dem Projekt hinzugefügt werden. Dazu benutzt man &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Rechts Klick -&amp;gt; Add files&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
*Aus dem &#039;&#039;&#039;&#039;&#039;CMSIS&#039;&#039;&#039;&#039;&#039; Ordner im Projekt Verzeichnis werden aus den Unterorder &#039;&#039;&#039;&#039;&#039;Include&#039;&#039;&#039;&#039;&#039; folgende Dateien dem Projekt hinzugefügt:&lt;br /&gt;
**arm_common_tables.h&lt;br /&gt;
**arm_const_structs.h&lt;br /&gt;
**arm_math.h&lt;br /&gt;
**core_cm4.h&lt;br /&gt;
**core_cm4_simd.h&lt;br /&gt;
**core_cmFunc.h&lt;br /&gt;
**core_cmInstr.h&lt;br /&gt;
*Alle Dateien aus den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projektes&lt;br /&gt;
*Die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; aus dem &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner&lt;br /&gt;
&lt;br /&gt;
So sollte die Struktur dann aussehen:&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_7.png|Anwenungs-Grundgerüst]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Da einige Dateien der Libraries später bearbeitet werden müssen und Schreibgeschützt sind, weise ich hier schonmal darauf hin, das der Schreibschutz in der IDE über &#039;&#039;&#039;&#039;&#039;Rechts Klick auf die Datei -&amp;gt; Properties -&amp;gt; Häkchen bei &amp;quot;File is read only&amp;quot; entfernen&#039;&#039;&#039;&#039;&#039; entfert werden kann.&lt;br /&gt;
&lt;br /&gt;
Damit die IDE die Header-Dateien der CMSIS Library auch finden kann, weil diese ja nicht im standard Include Ordner &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; liegen, muss unter &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Build Options -&amp;gt; Search Directories&#039;&#039;&#039;&#039;&#039; der Pfad &#039;&#039;&#039;&#039;&#039;CMSIS\Include&#039;&#039;&#039;&#039;&#039; hinzugefügt werden.&lt;br /&gt;
&lt;br /&gt;
Compiliert man jetzt das Projekt mit &#039;&#039;&#039;&#039;&#039;F7&#039;&#039;&#039;&#039;&#039; gibt es ein paar Fehler Meldungen, weil keine Controller-Reihe ausgewählt wurde. Ebenfalls unter &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Build Options -&amp;gt; Compiler Settings -&amp;gt; #defines&#039;&#039;&#039;&#039;&#039; wird der Define &#039;&#039;&#039;&#039;&#039;STM32F40_41xxx&#039;&#039;&#039;&#039;&#039; hinzugefügt.&lt;br /&gt;
&lt;br /&gt;
Beim erneuten Compilieren sollten sich nun keine neuen Fehler ergeben.&lt;br /&gt;
&lt;br /&gt;
===Das erste Programm===&lt;br /&gt;
Nachdem ein grundsätzliches &amp;quot;Gerüst&amp;quot; fertig ist, kann man den ersten Code schreiben.&lt;br /&gt;
main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC-&amp;gt;AHB1ENR |= RCC_AHB1ENR_GPIODEN;    //Takt für GPIO aktivieren&lt;br /&gt;
    GPIOD-&amp;gt;MODER |= GPIO_MODER_MODER15_0;   //GPIOD Pin15 als Ausgang&lt;br /&gt;
    GPIOD-&amp;gt;BSRRL |= GPIO_BSRR_BS_15;        //GPIOD Pin15 auf High ziehen&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039; wird dann der Debugger gestartet. Hat der Debugger das Projekt erfolgreich übertragen kann die Ausführung mit &#039;&#039;&#039;&#039;&#039;F5&#039;&#039;&#039;&#039;&#039; begonnen werden.&lt;br /&gt;
&lt;br /&gt;
==Libraries einbinden/verwenden==&lt;br /&gt;
===Einbinden der Standard-Peripheral-Library===&lt;br /&gt;
Um nicht immer die einzelnen Register, wie im ersten &amp;quot;bare-metal&amp;quot; Beispiel, aus dem Reference-Manual zu suchen und zu beschreiben, gibt es von ST die Standard Peripheral Library, die diese Aufgaben übernimmt und mit der sich die &amp;quot;normale/grundlegende&amp;quot; (Alles außer USB und Ethernet) Peripherie recht einfach steuern lässt. Um die Library zu verwenden erzeugt man wie oben beschrieben ein neues Grundgerüst und kopiert als erstes den Ordner &#039;&#039;&#039;&#039;&#039;Libraries\STM32F4xx_StdPeriph_Driver&#039;&#039;&#039;&#039;&#039; aus dem Standard-Peripheral-Library Download in das Projekt-Verzeichnis. Außerdem muss man die Datei &#039;&#039;&#039;&#039;&#039;Project\STM32F4xx_StdPeriph_Templates\stm32f4xx_conf.h&#039;&#039;&#039;&#039;&#039; ebenfalls aus dem Standard-Peripheral-Library Download in den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projektes kopieren. In der IDE fügt man den Include-Path &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\inc&#039;&#039;&#039;&#039;&#039; hinzufügen, wie bei der CMSIS-Library (s.o.).&lt;br /&gt;
Außerdem muss noch &#039;&#039;&#039;&#039;&#039;USE_STDPERIPH_DRIVER&#039;&#039;&#039;&#039;&#039; als Define in der IDE hinzugefügt werden (s.o.).&lt;br /&gt;
Danach fügt man die Source- und Include-Dateien aus dem Ordner &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\inc&#039;&#039;&#039;&#039;&#039; und &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\src&#039;&#039;&#039;&#039;&#039; dem Project mit &#039;&#039;&#039;&#039;&#039;&amp;lt;Project Name&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Add files&#039;&#039;&#039;&#039;&#039; hinzu, allerdings nur die, für welche auch der Controller die entsprechende Peripherie besitzt. Beim STM32F4-Discovery Board / STM32F407VG Controller dürfen also nicht folgende Dateien nicht mit hinzugefügt werden, weil diese Peripherie nur bei anderen Controller vorhanden ist:&lt;br /&gt;
&lt;br /&gt;
*stm32f4xx_dma2d.c/.h&lt;br /&gt;
*stm32f4xx_fmc.c/.h&lt;br /&gt;
*stm32f4xx_ltdc.c/.h&lt;br /&gt;
*stm32f4xx_sai.c/.h&lt;br /&gt;
&lt;br /&gt;
Daraus resultiert folgende Struktur:&lt;br /&gt;
&lt;br /&gt;
[[Datei:stdperiphlib_2.png|Header-Struktur]] [[Datei:stdperiphlib_1.png|Source-Struktur]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Anschließen kann die Standard-Peripheral-Library benutz werden.&lt;br /&gt;
main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);&lt;br /&gt;
&lt;br /&gt;
    GPIO_InitTypeDef GPIOD_InitStructure;&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Mode = GPIO_Mode_OUT;     //Als Ausgang&lt;br /&gt;
    GPIOD_InitStructure.GPIO_OType = GPIO_OType_PP;    //Push-Pull Betrieb&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Pin = GPIO_Pin_15;        //Pin 15 (STM32F4-Discovery: Blaue LED)&lt;br /&gt;
    GPIOD_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;  //Kein Pull-Up oder Pull-Down Widerstand aktiviert&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Speed = GPIO_Speed_25MHz; //25MHz Update-Rate&lt;br /&gt;
    GPIO_Init(GPIOD, &amp;amp;GPIOD_InitStructure);&lt;br /&gt;
&lt;br /&gt;
    GPIO_SetBits(GPIOD, GPIO_Pin_15);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Einbinden der DSP-Library===&lt;br /&gt;
STM32F3 / STM32F4 Microcontroller haben neben der FPU noch einen Digital-Signal-Processor (DSP). Die DSP dient hauptsächlich dazu, viele Daten schnell zu verarbeiten (z.B. Video- oder Audiosignal). Der CMSIS-Download beinhaltet dazu neben der eigentlichen CMSIS-Library auch noch eine DSP-Library. Diese Library stellt sowohl einfache, mathematische Funktionen wie addieren, multiplizieren usw. als auch komplexe Funktionen, wie z.B  einen IIR-Filter, zur Verfügung. Die DSP-Library ist weiter aufgeteilt in kleinere Module, wie z.B. BasicMathFunctions, FilteringFunctions usw. (siehe &#039;&#039;&#039;&#039;&#039;CMSIS\DSP-Library\Source&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
Um die DSP-Library zu verwenden müssen nur die Source-Files des benötigten Moduls einbinden.&lt;br /&gt;
(&#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Add files...&#039;&#039;&#039;&#039;&#039;). Außerdem muss in der &#039;&#039;&#039;&#039;&#039;main.c&#039;&#039;&#039;&#039;&#039; der Include &#039;&#039;&#039;&#039;&#039;arm_math.h&#039;&#039;&#039;&#039;&#039; eingebunden werden. Aus irgendeinem Grund gibt es dann jedoch die Warnung: &amp;quot;Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)&amp;quot;. Ich hab noch nicht rausgefunden, wieso diese Warnung auftaucht. Die Warnung verschwindet, wenn man in der &#039;&#039;&#039;&#039;&#039;Build options...&#039;&#039;&#039;&#039;&#039; das Define &#039;&#039;&#039;&#039;&#039;__FPU_PRESENT&#039;&#039;&#039;&#039;&#039; hinzufügt (Ich weiß selber das das keine schöne Lösung ist, eine andere hab ich jedoch noch nicht gefunden). Jetzt kann die DSP-Library verwedet werden. Das Beispiel multipliziert zwei Buffer miteinander. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
#include &amp;quot;arm_math.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    float32_t x[1024];&lt;br /&gt;
    float32_t y[1024];&lt;br /&gt;
    float32_t z[1024];&lt;br /&gt;
&lt;br /&gt;
    for(uint16_t i = 0; i &amp;lt; 1024; i++)&lt;br /&gt;
    {&lt;br /&gt;
        x[i] = i;&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for(uint16_t i = 0; i &amp;lt; 1024; i++)&lt;br /&gt;
    {&lt;br /&gt;
        y[i] = PI;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    arm_mult_f32(x, y, z, 1024);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Startup-Code, Linker-Script, Takt, FPU usw.==&lt;br /&gt;
===Startup-Code===&lt;br /&gt;
Em::Blocks fügt standardmäßig einen Startup-Code mit in das Projekt ein. Die wichtigsten Dinge die darin erledigt werden sind folgende:&lt;br /&gt;
&lt;br /&gt;
*Stack und Heap wird angelgt&lt;br /&gt;
*Die Vector-Table wird angelegt&lt;br /&gt;
*Ein Default Reset-Handler wird implementiert, dieser erledigt folgende aufgaben:&lt;br /&gt;
**Kopieren der definierten Daten aus dem Flash in den SRAM&lt;br /&gt;
**&#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; wird aufgerfen, wenn &#039;&#039;&#039;&#039;&#039;__NO_SYSTEM_INIT&#039;&#039;&#039;&#039;&#039; nicht definiert ist&lt;br /&gt;
**Sprung in die &#039;&#039;&#039;&#039;&#039;main()&#039;&#039;&#039;&#039;&#039; Funktion&lt;br /&gt;
*Allen anderen Interrupt-Handler wird eine Default-Funktion &#039;&#039;&#039;&#039;&#039;def_irq_handler&#039;&#039;&#039;&#039;&#039; mit einer &#039;&#039;&#039;&#039;&#039;while(1)&#039;&#039;&#039;&#039;&#039;-Schleife zugewiesen, falls kein anderer Interrupt-Handler existiert.&lt;br /&gt;
&lt;br /&gt;
Normalerweise muss am Startup-Code nichts verändert werden.&lt;br /&gt;
&lt;br /&gt;
===Linker-Script===&lt;br /&gt;
Em::Blocks stellt zwei fertige Linker-Scripts bereit, eins für die Ausführung des Programmes aus dem Flash (&#039;&#039;&#039;&#039;&#039;*_flash.ld&#039;&#039;&#039;&#039;&#039;), das andere für die Ausführung aus dem SRAM (&#039;&#039;&#039;&#039;&#039;*_sram.ld&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Normalerweise muss auch hier nichts geändert werden, es sei den Daten sollen in bestimmten Adressbereichen abgelegt werden (z.B. im Core-Coupled RAM), was ich später noch zum Tutorial hinzufüge.&lt;br /&gt;
&lt;br /&gt;
===Der Takt===&lt;br /&gt;
Jeder Controller oder Prozessor braucht einen Takt, indem er die einzelnen Maschinen-Befehle abarbeiten kann.&lt;br /&gt;
Bei den STM32 Mikrocontrollern kann dieser Takt aus verschiedenen Quellen kommen:&lt;br /&gt;
&lt;br /&gt;
1. High Speed Internal Oszillator (HSI)&lt;br /&gt;
&lt;br /&gt;
2. High Speed External Oszillator (HSE)&lt;br /&gt;
&lt;br /&gt;
3. Low Speed Internal Oszillator (LSI)&lt;br /&gt;
&lt;br /&gt;
4. Low Speed External Oszillator (LSE)&lt;br /&gt;
&lt;br /&gt;
5. Phase-Locked Loop (PLL) (generiert den Takt aus den ersten vier Taktquellen durch Teiler und Faktoren)&lt;br /&gt;
&lt;br /&gt;
Nach einem Reset wird der Controller aus der HSI Taktquelle versorgt (16MHz beim STM32F407VG). Um die voll Performance des Controllers zu erreichen muss die PLL verwendet werden, welche den Takt durch geschickte Teiler und Faktoren vervielfältigt, sodass am Ende der Controller mit der maximalen Taktfrequenz läuft. Die notwendige Initialisierung der PLL findet in der Funktion &#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; statt. Die PLL erzeugt zunächst einen Basistakt:&lt;br /&gt;
&lt;br /&gt;
PLL_VCO = (F_HSE / PLL_M) * PLL_N&lt;br /&gt;
&lt;br /&gt;
Aus diesem Takt wird dann der Takt für den Controller-Kern abgeleitet:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = PLL_VCO / PLL_P&lt;br /&gt;
&lt;br /&gt;
Und der Takt für SDIO / USB / RNG (48MHz):&lt;br /&gt;
&lt;br /&gt;
48MHz = PLL_VCO / PLL_Q&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Durch weiter Teiler werden, die Takte für die einzelnen Busse erzeugt, da diese nicht alle beliebig schnell betrieben werden dürfen.&lt;br /&gt;
&lt;br /&gt;
Genaue Angaben findet man zu dem jeweiligen Clock-System des Controllers im Reference Manual.&lt;br /&gt;
&lt;br /&gt;
Ein Blick in den &amp;quot;Kommentar-Header&amp;quot; verrät, dass von einem externen (HSE) Oszillator von 25MHz ausgegangen wird, der die PLL versorgen soll.&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((25MHz / PLL_M(25)) * PLL_N(336)) / PLL_P(2) = 168MHz&lt;br /&gt;
&lt;br /&gt;
Allerdings stimmt diese Rechnung natürlich nur, wenn wirklich ein 25MHz Quarz am Controller angeschlossen ist. Auf dem STM32F4-Discovery Board befindet sich aber nur ein 8MHz Quarz. Demnach gilt:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((8MHz / PLL_M(25)) * PLL_N(336)) / PLL_P(2) = 53.76MHz&lt;br /&gt;
&lt;br /&gt;
Der Controller läuft also nur mit 53.76MHz, wenn wie ober beschrieben ein Projekt erstellt wird. Allerdings kann dieses Problem durch ändern von den betroffen Defines behoben werden:&lt;br /&gt;
 &lt;br /&gt;
*Dazu geht man in die &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; Datei und passt zur Vollständigkeit erstmal die zum Controller passende Tabelle im &amp;quot;Kommentar-Header&amp;quot; an (Z.57f):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      HSE Frequency(Hz)                      | 8000000&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      PLL_M                                  | 8&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Danach passt man den PPL_M Define (Z.254) an:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/************************* PLL Parameters *************************************/&lt;br /&gt;
/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */&lt;br /&gt;
#define PLL_M      8&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Außerdem muss man den HSE_VALUE Define in der &#039;&#039;&#039;&#039;&#039;inc/stm32f4xx.h&#039;&#039;&#039;&#039;&#039; angepasst werden (Z.122):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#if !defined  (HSE_VALUE)&lt;br /&gt;
  #define HSE_VALUE    ((uint32_t)8000000) /*!&amp;lt; Value of the External oscillator in Hz */&lt;br /&gt;
&lt;br /&gt;
#endif /* HSE_VALUE */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine neue Berechnung zeigt:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((8MHz / PLL_M(8)) * PLL_N(336)) / PLL_P(2) = 168MHz&lt;br /&gt;
&lt;br /&gt;
Jetzt läuft der Controller mit maximaler Geschwindigkeit.&lt;br /&gt;
&lt;br /&gt;
Die Theorie wird durch folgendes Programm verifiziert. Der geviertelte System-Takt SYSCLK wir am Pin PC9 ausgegeben. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);&lt;br /&gt;
&lt;br /&gt;
    GPIO_InitTypeDef GPIOC_InitStructure;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Mode = GPIO_Mode_AF;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_OType = GPIO_OType_PP;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Pin = GPIO_Pin_9;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;&lt;br /&gt;
    GPIO_Init(GPIOC, &amp;amp;GPIOC_InitStructure);&lt;br /&gt;
&lt;br /&gt;
    RCC_MCO2Config(RCC_MCO2Source_SYSCLK, RCC_MCO2Div_4);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Die FPU===&lt;br /&gt;
====Allgemeines====&lt;br /&gt;
Damit die FPU richtig verwendet wird, müssen normalerweise zwei Bedingungen erfüllt sein:&lt;br /&gt;
&lt;br /&gt;
1. Der Controller muss in der Initialisierung-Funktion &#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; in &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; die FPU Hardware-seitig aktivieren&lt;br /&gt;
&lt;br /&gt;
2. Damit die FPU auch was zu tuen bekommt, müssen vom Compiler FPU-Instructions erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
Die Em::Blocks IDE verwendet standardmäßig die FPU, wenn eine Vorhanden ist. Hier wird die FPU Hardware-seitig aktiviert (&#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; Z.341):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* FPU settings ------------------------------------------------------------*/&lt;br /&gt;
  #if (__FPU_PRESENT == 1) &amp;amp;&amp;amp; (__FPU_USED == 1)&lt;br /&gt;
    SCB-&amp;gt;CPACR |= ((3UL &amp;lt;&amp;lt; 10*2)|(3UL &amp;lt;&amp;lt; 11*2));  /* set CP10 and CP11 Full Access */&lt;br /&gt;
  #endif&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
__FPU_PRESENT wird in der &#039;&#039;&#039;&#039;&#039;stm32f4xx.h&#039;&#039;&#039;&#039;&#039; definiert.&lt;br /&gt;
__FPU_USED wird von der IDE übernommen (siehe Build-Log): &#039;&#039;&#039;&#039;&#039;-D__FPU_USED&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Außerdem wird der Compiler von der IDE standardmäßig mit dem Argument &#039;&#039;&#039;&#039;&#039;-mfloat-abi=hard&#039;&#039;&#039;&#039;&#039; aufgerufen, wodurch FPU-Instructions erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
====FPU abschalten====&lt;br /&gt;
Um die FPU ab zu schalten (Mir würde jetzt nur Strom sparen als Grund einfallen) geht man wie folgt vor:&lt;br /&gt;
&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick Build options -&amp;gt; Device -&amp;gt; Policy&#039;&#039;&#039;&#039;&#039; wählt man &#039;&#039;&#039;&#039;&#039;Use target settings&#039;&#039;&#039;&#039;&#039; und über nimmt die Einstellungen, die vorher dort eingetragen waren, allerdings lässt man das Feld &#039;&#039;&#039;&#039;&#039;FP-hardware&#039;&#039;&#039;&#039;&#039; frei.&lt;br /&gt;
&lt;br /&gt;
[[Datei:fpu_1.png|FPU Abschalten Schritt 1]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;Compiler Settings -&amp;gt; Policy&#039;&#039;&#039;&#039;&#039; wählt man dann &#039;&#039;&#039;&#039;&#039;Use target options only&#039;&#039;&#039;&#039;&#039;. Dann kann man unter &#039;&#039;&#039;&#039;&#039;Categories&#039;&#039;&#039;&#039;&#039; die Option &#039;&#039;&#039;&#039;&#039;ARM FPU architecture&#039;&#039;&#039;&#039;&#039; auswählen. Dort stehen dann drei Möglichkeiten für die FPU zur Verfügung:&lt;br /&gt;
&lt;br /&gt;
1. Software-FPU-Library für Gleitkomma-Berechnung verwenden - Keine FPU-Instructions werden generiert (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=soft&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
2. Eine Mischung aus Software- und Hardware-FPU wird verwendet (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=softfp&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
3. Hardware-FPU wird für Gleitkomma-Berechnungen verwendet (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=hard&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
[[Datei:fpu_2.png|FPU Abschalten Schritt 2]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Um die FPU ab zu schalten wählt man natürlich die erste Möglichkeit.&lt;br /&gt;
Bei der 2. und 3. Möglichkeit fügt die IDE auch den Define &#039;&#039;&#039;&#039;&#039;__FPU_USED&#039;&#039;&#039;&#039;&#039; hinzu. Bei Der ersten Möglichkeit nicht. Der Code muss also nicht verändert / auskommentiert werden.&lt;br /&gt;
&lt;br /&gt;
Um die FPU wieder zu aktivieren müssen alle Schritte wieder rückgängig gemacht werden.&lt;br /&gt;
&lt;br /&gt;
Am besten ist es einfach mal alle Möglichkeiten im Einzelschritt durch zu probieren. Dann stellt man schnell fest, ob die FPU aktiviert wir oder nicht. Ein Blick in den erweiterten &#039;&#039;&#039;&#039;&#039;Build-Log&#039;&#039;&#039;&#039;&#039; gibt auch schnell Aufschluss darüber, wie der Compiler aufgerufen wird (siehe Kapitel [http://www.mikrocontroller.net/articles/STM32_-_Einstieg_mit_Em::Blocks#Compilieren Compilieren]).&lt;br /&gt;
&lt;br /&gt;
====Test Programm für die FPU====&lt;br /&gt;
Hier ein kleines Testprogramm, dass misst wie viele Taktzyklen für eine Gleitkomma-Multiplikation gebraucht werden. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define CORE_SysTickEn()    (*((u32*)0xE0001000)) = 0x40000001&lt;br /&gt;
#define CORE_SysTickDis()   (*((u32*)0xE0001000)) = 0x40000000&lt;br /&gt;
#define CORE_GetSysTick()   (*((u32*)0xE0001004))&lt;br /&gt;
&lt;br /&gt;
uint32_t t1, t2, dt;&lt;br /&gt;
float x, y, z;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    x = 53.64f;&lt;br /&gt;
    y = 0.27f;&lt;br /&gt;
&lt;br /&gt;
    CORE_SysTickEn();&lt;br /&gt;
    t1 = CORE_GetSysTick();&lt;br /&gt;
&lt;br /&gt;
    z = x * y;&lt;br /&gt;
&lt;br /&gt;
    t2 = CORE_GetSysTick();&lt;br /&gt;
    CORE_SysTickDis();&lt;br /&gt;
&lt;br /&gt;
    dt = (t2 - t1) - 9; //9 Takt-Zyklen werden für die Messung gebraucht &lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Booten aus dem SRAM==&lt;br /&gt;
STM32 Controller haben die Möglichkeit Code aus dem Flash als auch aus dem SRAM auszuführen. Um eine Anwenung per Debugger in des SRAM zu laden sind nur wenige Schritte erforderlich:&lt;br /&gt;
&lt;br /&gt;
*Um das Linkerscript für den SRAM zu verwenden geht man zu: &#039;&#039;&#039;&#039;&#039;Build options... -&amp;gt; Device&#039;&#039;&#039;&#039;&#039; dort wählt man unter &#039;&#039;&#039;&#039;&#039;Policy&#039;&#039;&#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;Use target settings&#039;&#039;&#039;&#039;&#039; aus und übernimmt die vorherigen Einstellungen, nur unter &#039;&#039;&#039;&#039;&#039;Linker script*&#039;&#039;&#039;&#039;&#039; gibt man &#039;&#039;&#039;&#039;&#039;.\stm32f407vg_sram.ld&#039;&#039;&#039;&#039;&#039; an&lt;br /&gt;
&lt;br /&gt;
*Dann muss man noch unter &#039;&#039;&#039;&#039;&#039;Debug -&amp;gt; Interfaces -&amp;gt; Settings&#039;&#039;&#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;Vector table start&#039;&#039;&#039;&#039;&#039; auf 0x20000000 ändern und &#039;&#039;&#039;&#039;&#039;Execute from RAM&#039;&#039;&#039;&#039;&#039; auswählen.&lt;br /&gt;
&lt;br /&gt;
Anschließend kann man die Anwendung ganz normal debuggen. Nach einem Reset muss die Anwenung erneut mit dem Debugger gestartet werden.&lt;br /&gt;
&lt;br /&gt;
=Fortsetzung folgt..=&lt;br /&gt;
Kritik, Wünsche usw. sind gerne erwünscht, am besten hier in den Thread posten: [http://www.mikrocontroller.net/topic/323750 Neues STM32 Tutorial]&lt;br /&gt;
&lt;br /&gt;
[[Category:ARM]]&lt;br /&gt;
[[Category:STM32]]&lt;/div&gt;</summary>
		<author><name>Avrprogger</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=STM32_-_Einstieg_mit_Em::Blocks&amp;diff=81541</id>
		<title>STM32 - Einstieg mit Em::Blocks</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=STM32_-_Einstieg_mit_Em::Blocks&amp;diff=81541"/>
		<updated>2014-02-11T16:38:16Z</updated>

		<summary type="html">&lt;p&gt;Avrprogger: ghj&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In diesem Tutorial werde ich versuchen, möglichst einfach, die ersten Schritte zur Entwicklung von STM32 Anwenungen mit der Em::Blocks IDE zu erklären. Hier soll nicht so stark auf die einzelnen Peripherie-Module der Controller eingegangen werden, sondern mehr auf die IDE und die verschieden Libraries, wie die CMSIS Library, die DSP-Library, die Standard-Peripheral-Library, die USB-Library und vllt. über Ethernet. Ich denke ein Kapitel zu FreeRTOS wird es auch geben. Auserdem steht im Vordergrund Sachen wie z.B. booten aus dem SRAM, In-Application-Programming, FPU, Core-Coupled-RAM usw. Mal sehn wie weit ich komme ;)&lt;br /&gt;
&lt;br /&gt;
==Die Entwicklungsumgebung==&lt;br /&gt;
===Hardware===&lt;br /&gt;
Zum testen der Anwendungen, benutze ich das STM32F4-Discovery Board, welches einen Debugger, Peripherie und natürlich einen STM32 Controller (STM32F407VGT6) enthält. Deshalb sind alle Beispiele hier für den STM32F407VG Controller ausgelegt, können aber meisten 1:1 auf andere Controller portiert werden. Ich werde auch möglichsts keine STM32F4-Discovery Board spezifischen Libraries verwenden, damit der Portierungs-Vorgang möglichsts einfach bleibt.&lt;br /&gt;
&lt;br /&gt;
===Software===&lt;br /&gt;
In diesem Tutorial verwende ich [http://www.emblocks.org/ Em::Blocks] als IDE. Em::Blocks ist eine kostenlose, uneingeschränkte IDE, die alle STM32 Mikrcontroller unterstützt und sehr einfach zu bedienen ist.&lt;br /&gt;
nach dem Download kann die IDE per Dialog, sehr einfach, installiert werden. Als Compiler beinhaltet Em::Blocks den &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
Die IDE unterstützt zurzeit den ST-Link, den J-Link und es gibt eine Generic-Vorlage, durch welche andere Debugger konfiguriert werden können.&lt;br /&gt;
&lt;br /&gt;
Außerdem muss noch der passende Treiber für den Debugger installiert werden. Verwendet man ein Discovery-Board muss der [http://www.st.com/web/catalog/tools/FM146/CL1984/SC724/SS1677/PF251168 ST-Link/V2]-Treiber heruntergeladen und installiert werden. (Die Installation muss evtl. als Administrator ausgeführt werden, da sonst die Installation unvollständig wird.) Nach der Installation des Treibers kann man den Debugger über die entsprechende USB Schnittstelle an den PC anschließen und es sollte die Meldung von Windows kommen, dass der richtige Treiber gefunden wurde.&lt;br /&gt;
&lt;br /&gt;
===Libraries===&lt;br /&gt;
Zum programmieren benötigt man noch die [http://www.arm.com/products/processors/cortex-m/cortex-microcontroller-software-interface-standard.php CMSIS] und die Standard-Peripheral-Library (z.B. für die F4 Controller [http://www.st.com/stonline/stappl/productcatalog/app?page=partNumberSearchPage&amp;amp;levelid=SS1577&amp;amp;parentid=1743&amp;amp;resourcetype=SW Standard-Peripheral-Library-F4]), die man am besten in einen Ordner (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\STM32&#039;&#039;&#039;&#039;&#039;) entpackt&lt;br /&gt;
&lt;br /&gt;
==Basis-Wissen zur IDE==&lt;br /&gt;
Einige Grundfunktionalitäten der IDE:&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von Dateien zum Projekt===&lt;br /&gt;
Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf &amp;lt;ProjektName&amp;gt; -&amp;gt; Add files...&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Enfernen von Dateien aus dem Projekt===&lt;br /&gt;
Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf die Datei / mehrere Dateien auswählen -&amp;gt; Remove file from project&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
Die Dateien werden lediglich aus dem Projekt entfernt und nicht von der Festplatte gelöscht.&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von Include-Pfaden===&lt;br /&gt;
Sofern die Include-Datei(en) nicht im standard Include-Ordner &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; des Projektes liegen, muss man den Pfad zum Projekt hinzufügen, damit der Compiler die Include-Dateien später auch finden kann. Man geht wie folgt vor: Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf &amp;lt;ProjektName&amp;gt; -&amp;gt; Build options... -&amp;gt; Search Directories -&amp;gt; Add&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von globalen Defines zum Build===&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; #defines&#039;&#039;&#039;&#039;&#039; können globale Defines hinzugefügt werden.&lt;br /&gt;
&lt;br /&gt;
===Compilieren===&lt;br /&gt;
Entweder über das &#039;&#039;&#039;&#039;&#039;Build&#039;&#039;&#039;&#039;&#039; Menü oder über &#039;&#039;&#039;&#039;&#039;F7&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Um eine genau Ausgabe des Compiler-Aufrufes mit allen Argumenten zu bekommen, geht man im &#039;&#039;&#039;&#039;&#039;Settings&#039;&#039;&#039;&#039;&#039; Menü auf &#039;&#039;&#039;&#039;&#039;Tools...&#039;&#039;&#039;&#039;&#039; und dann auf &#039;&#039;&#039;&#039;&#039;Toolchain executables&#039;&#039;&#039;&#039;&#039;. Ganz unten, unter &#039;&#039;&#039;&#039;&#039;Logging&#039;&#039;&#039;&#039;&#039; kann man dann &#039;&#039;&#039;&#039;&#039;Full command line&#039;&#039;&#039;&#039;&#039; auswählen.&lt;br /&gt;
&lt;br /&gt;
====Compiler Optionen====&lt;br /&gt;
=====Optimierung=====&lt;br /&gt;
Standardmäßig verwendet Em::Blocks keine Optimierung. Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; Categories: Optimization&#039;&#039;&#039;&#039;&#039; kann zwischen verschieden Optimierungen ausgewählt werden.&lt;br /&gt;
&lt;br /&gt;
=====Verschiedene C-Standards=====&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; Categories: Language standard&#039;&#039;&#039;&#039;&#039; kann man zwischen verschieden C-Standard auswählen, wie z.B, C99.&lt;br /&gt;
(Mit C99 können auch die Lauf-Variable in der for-Schleife deklariert werden: for(int i;..))&lt;br /&gt;
&lt;br /&gt;
===Debuggen===&lt;br /&gt;
*Als erstes den Debugger starten über das &#039;&#039;&#039;&#039;&#039;Debug&#039;&#039;&#039;&#039;&#039; Menü und &#039;&#039;&#039;&#039;&#039;Start/stop Debug Session&#039;&#039;&#039;&#039;&#039; oder über &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
*Danach läuft die Anwendung auf dem Controller und warten im &#039;&#039;&#039;&#039;&#039;Reset_Handler&#039;&#039;&#039;&#039;&#039; auf Einzelschritt- bzw. Run- Befehle (&#039;&#039;&#039;&#039;&#039;F5, F10, F11&#039;&#039;&#039;&#039;&#039; usw..(siehe &#039;&#039;&#039;&#039;&#039;Debug-Menü&#039;&#039;&#039;&#039;&#039; für alle Möglichkeiten))&lt;br /&gt;
&lt;br /&gt;
*Mit &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039; wird die Debug-Session auch wieder beendet&lt;br /&gt;
&lt;br /&gt;
*Unter &#039;&#039;&#039;&#039;&#039;Debug -&amp;gt; Interfaces -&amp;gt; Target settings&#039;&#039;&#039;&#039;&#039; können Eigenschaften, wie z.B &#039;&#039;&#039;&#039;&#039;Run to main()&#039;&#039;&#039;&#039;&#039; aktiviert werden.&lt;br /&gt;
&lt;br /&gt;
===Projekt als Template abspeichern===&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;File -&amp;gt; Save project as template...&#039;&#039;&#039;&#039;&#039;. Das Template erscheint dann im Projekt-Dialog unter &#039;&#039;&#039;&#039;&#039;User templates&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Das erste Projekt erstellen==&lt;br /&gt;
Hier erkläre ich, wie man am Besten (aus meiner Sicht), ein neues Projekt von Grund auf erstellt, sodass man hinterher, den Controller-Kern über die CMSIS-Library und die Peripherie über die Register steuern kann.&lt;br /&gt;
&lt;br /&gt;
===1. Projekt mit der IDE erstellen===&lt;br /&gt;
Nach der Installation der oben beschriebenen Komponenten erstellt man am besten ein Verzeichnis (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\EmBlocks&#039;&#039;&#039;&#039;&#039;), indem später alle Projekte gespeichert werden. Für Libraries kann man auch noch ein Verzeichnis (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\STM32&#039;&#039;&#039;&#039;&#039;) erstellen, wo alle Libraries gespeichert werden, die man für die Projekt brauchen.&lt;br /&gt;
&lt;br /&gt;
Als nächstes starten man EmBlocks. Bei dem ersten Start öffnet sich ein Fenster, wo verschiedene Compiler angezeigt werden, die Em::Blocks findet. Dort wählt man den &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039; aus und klickt &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039;. Nun sollte sich das Hauptfenster von Em::Blocks öffnen. Über &#039;&#039;&#039;&#039;&#039;Create a new Project&#039;&#039;&#039;&#039;&#039; oder &#039;&#039;&#039;&#039;&#039;File -&amp;gt; New -&amp;gt; Project&#039;&#039;&#039;&#039;&#039; ruft man den Projekt-Dialog auf und kann ein neues Projekt erzeugen.&lt;br /&gt;
&lt;br /&gt;
Auf der Ersten Seite wählen man den &#039;&#039;&#039;&#039;&#039;STmicro-ARM&#039;&#039;&#039;&#039;&#039; Projekt-Typ aus.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_1.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auf der nächsten Seite wird man darauf hingewiesen, dass das der entsprechende Projekt-Typ-Dialog ausgeführt wird. Hier kann man ein Häkchen bei &#039;&#039;&#039;&#039;&#039;Skip this page next time&#039;&#039;&#039;&#039;&#039; setzen und auf &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; klicken.&lt;br /&gt;
&lt;br /&gt;
Im nächsten Schritt wählen man das zuvor erstellt Verzeichnis unter &#039;&#039;&#039;&#039;&#039;Folder to create Project in&#039;&#039;&#039;&#039;&#039; aus, indem später alle Projekt gespeichert werden. Außerdem geben wir dem Projekt einen Namen (z.B. &#039;&#039;&#039;&#039;&#039;FirstProject&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_2.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danach muss man einen Compiler auswählen und bestimmen, welche Projekt-Konfigurationen erszeugt werden sollen. Unter &#039;&#039;&#039;&#039;&#039;Compiler&#039;&#039;&#039;&#039;&#039; wählt man &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039; und man kann das Häkchen bei &#039;&#039;&#039;&#039;&#039;Create &amp;quot;Release&amp;quot; configuration&#039;&#039;&#039;&#039;&#039; entfernen, da diese unnötig ist, die Debug-Konfiguration sollte eig. immer ausreichen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_3.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auf den folgenden Seite wird der Controller ausgewählt. Verwendet man ein STM32F4-Discovery Board müssen folgende Dinge gewählt werden: &#039;&#039;&#039;&#039;&#039;Cortex_M4 (F3xx - F4xx) -&amp;gt; STM32F4xx (Cortex M4 with FPU) -&amp;gt; STM32F407VG&#039;&#039;&#039;&#039;&#039;. Leider sind die Auswahl Möglichkeiten nicht ganz richtig, da auch die F3 Controller einen Cortex M4 Kern und eine FPU haben (Ist aber nicht so wichtig, ist nur eine formale Sache). Außerdem entfernt man das Häkchen bei &#039;&#039;&#039;&#039;&#039;Standard Peripherals Library&#039;&#039;&#039;&#039;&#039; (Wie man die Standard-Peripheral-Library einbindet und verwendet erkläre ich später). Man kann auch das Häkchen bei &#039;&#039;&#039;&#039;&#039;Create hex file for Realease target&#039;&#039;&#039;&#039;&#039; entfernen.&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;Stack Size&#039;&#039;&#039;&#039;&#039; und &#039;&#039;&#039;&#039;&#039;Heap Size&#039;&#039;&#039;&#039;&#039; wird die Größe von Stack und Heap festgelegt. Für eine erste Anwendung kann man die Einstellungen so lassen (Stack-Size: 0x0100 =&amp;gt; 256 Byte Stack und Heap-Size: 0x0000 =&amp;gt; kein Heap). Mit &#039;&#039;&#039;&#039;&#039;Finish&#039;&#039;&#039;&#039;&#039; ist der Projekt Dialog abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_4.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danach sollten sich zwei neue Fenster öffnen, um die Debug-Eigenschaften fest zu legen.&lt;br /&gt;
Verwendet man ein Discovery Board/ST-Link müssen die Einstellungen wie auf dem Bild gewählt werden. Über den Button &#039;&#039;&#039;&#039;&#039;Settings&#039;&#039;&#039;&#039;&#039; öffnet sich das zweite Fenster, falls sich dieses nicht schon von alleine öffnen sollte. Nach den Schließen der Fenster über &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; ist der Projekt Dialog beendet und ein neues Projekt steht zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_5_1.png|Debug Eigenschaften 1. Fenster]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_5_2.png|Debug Eigenschaften 2. Fenster]]&lt;br /&gt;
&lt;br /&gt;
===2. CMSIS-Library und Startup-Code hinzufügen===&lt;br /&gt;
Wenn man sich, nachdem man ein neues Projekt in der IDE erstellt hat, die bereits vorhandenen Dateien im Projekt ansieht, stellt man fest, das bereits ein Ordner &#039;&#039;&#039;&#039;&#039;cmsis&#039;&#039;&#039;&#039;&#039; existiert, der einige wichtige Include-Dateien der CMSIS-Library enthält. Allerdings sind das wirklich nur die wichtigsten Include-Dateien der CMSIS-Library und dazu noch, die aus einer älternen Version. Ich ziehe es deshalb vor die &amp;quot;Mini-CMSIS-Libraray&amp;quot; und die &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c/.h&#039;&#039;&#039;&#039;&#039; Dateien des Projektes durch aktuellere Versionen zu ersetzen. So ist später auch die Integration  von anderen Libraries, wie z.B. der CMSIS-DSP-Libarary einfacher.  &lt;br /&gt;
&lt;br /&gt;
Zunächst gehen man in das Projekt-Verzeichnis und löscht:&lt;br /&gt;
*Den Ordner &#039;&#039;&#039;&#039;&#039;cmsis&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Alle Dateien im Include Verzeichnis &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; im &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner&lt;br /&gt;
&lt;br /&gt;
Außerdem entfernt man auch alle gelöschten Dateien in der IDE aus dem Projekt mit &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Rechts Klick -&amp;gt; Remove file from project&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Es sollte folgende Verzeichnis Struktur überbleiben:&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_6.png|Überbleibende Dateien]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Jetzt müssen die gelöschten Dateien durch die aktuelleren ersetzt werden.&lt;br /&gt;
&lt;br /&gt;
*Dazu kopieren man den gesamten Ordner &#039;&#039;&#039;&#039;&#039;CMSIS&#039;&#039;&#039;&#039;&#039; aus dem CMSIS Download in das Projekt Verzeichnis.&lt;br /&gt;
&lt;br /&gt;
*Aus dem Standard-Peripheral-Library Download kopiert man von &#039;&#039;&#039;&#039;&#039;Libraries\CMSIS\Device\ST\STM32F4xx\Include&#039;&#039;&#039;&#039;&#039; alle Dateien in den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projekt Verzeichnisses&lt;br /&gt;
&lt;br /&gt;
*Aus der Standard-Peripheral-Library kopieren man ebenfalls von &#039;&#039;&#039;&#039;&#039;Libraries\CMSIS\Device\ST\STM32F4xx\Source\Templates&#039;&#039;&#039;&#039;&#039; die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; in den &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner des Projekts&lt;br /&gt;
&lt;br /&gt;
Anschließend müssen die neuen Dateien in der IDE dem Projekt hinzugefügt werden. Dazu benutzt man &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Rechts Klick -&amp;gt; Add files&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
*Aus dem &#039;&#039;&#039;&#039;&#039;CMSIS&#039;&#039;&#039;&#039;&#039; Ordner im Projekt Verzeichnis werden aus den Unterorder &#039;&#039;&#039;&#039;&#039;Include&#039;&#039;&#039;&#039;&#039; folgende Dateien dem Projekt hinzugefügt:&lt;br /&gt;
**arm_common_tables.h&lt;br /&gt;
**arm_const_structs.h&lt;br /&gt;
**arm_math.h&lt;br /&gt;
**core_cm4.h&lt;br /&gt;
**core_cm4_simd.h&lt;br /&gt;
**core_cmFunc.h&lt;br /&gt;
**core_cmInstr.h&lt;br /&gt;
*Alle Dateien aus den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projektes&lt;br /&gt;
*Die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; aus dem &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner&lt;br /&gt;
&lt;br /&gt;
So sollte die Struktur dann aussehen:&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_7.png|Anwenungs-Grundgerüst]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Da einige Dateien der Libraries später bearbeitet werden müssen und Schreibgeschützt sind, weise ich hier schonmal darauf hin, das der Schreibschutz in der IDE über &#039;&#039;&#039;&#039;&#039;Rechts Klick auf die Datei -&amp;gt; Properties -&amp;gt; Häkchen bei &amp;quot;File is read only&amp;quot; entfernen&#039;&#039;&#039;&#039;&#039; entfert werden kann.&lt;br /&gt;
&lt;br /&gt;
Damit die IDE die Header-Dateien der CMSIS Library auch finden kann, weil diese ja nicht im standard Include Ordner &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; liegen, muss unter &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Build Options -&amp;gt; Search Directories&#039;&#039;&#039;&#039;&#039; der Pfad &#039;&#039;&#039;&#039;&#039;CMSIS\Include&#039;&#039;&#039;&#039;&#039; hinzugefügt werden.&lt;br /&gt;
&lt;br /&gt;
Compiliert man jetzt das Projekt mit &#039;&#039;&#039;&#039;&#039;F7&#039;&#039;&#039;&#039;&#039; gibt es ein paar Fehler Meldungen, weil keine Controller-Reihe ausgewählt wurde. Ebenfalls unter &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Build Options -&amp;gt; Compiler Settings -&amp;gt; #defines&#039;&#039;&#039;&#039;&#039; wird der Define &#039;&#039;&#039;&#039;&#039;STM32F40_41xxx&#039;&#039;&#039;&#039;&#039; hinzugefügt.&lt;br /&gt;
&lt;br /&gt;
Beim erneuten Compilieren sollten sich nun keine neuen Fehler ergeben.&lt;br /&gt;
&lt;br /&gt;
===Das erste Programm===&lt;br /&gt;
Nachdem ein grundsätzliches &amp;quot;Gerüst&amp;quot; fertig ist, kann man den ersten Code schreiben.&lt;br /&gt;
main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC-&amp;gt;AHB1ENR |= RCC_AHB1ENR_GPIODEN;    //Takt für GPIO aktivieren&lt;br /&gt;
    GPIOD-&amp;gt;MODER |= GPIO_MODER_MODER15_0;   //GPIOD Pin15 als Ausgang&lt;br /&gt;
    GPIOD-&amp;gt;BSRRL |= GPIO_BSRR_BS_15;        //GPIOD Pin15 auf High ziehen&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039; wird dann der Debugger gestartet. Hat der Debugger das Projekt erfolgreich übertragen kann die Ausführung mit &#039;&#039;&#039;&#039;&#039;F5&#039;&#039;&#039;&#039;&#039; begonnen werden.&lt;br /&gt;
&lt;br /&gt;
==Libraries einbinden/verwenden==&lt;br /&gt;
===Einbinden der Standard-Peripheral-Library===&lt;br /&gt;
Um nicht immer die einzelnen Register, wie im ersten &amp;quot;bare-metal&amp;quot; Beispiel, aus dem Reference-Manual zu suchen und zu beschreiben, gibt es von ST die Standard Peripheral Library, die diese Aufgaben übernimmt und mit der sich die &amp;quot;normale/grundlegende&amp;quot; (Alles außer USB und Ethernet) Peripherie recht einfach steuern lässt. Um die Library zu verwenden erzeugt man wie oben beschrieben ein neues Grundgerüst und kopiert als erstes den Ordner &#039;&#039;&#039;&#039;&#039;Libraries\STM32F4xx_StdPeriph_Driver&#039;&#039;&#039;&#039;&#039; aus dem Standard-Peripheral-Library Download in das Projekt-Verzeichnis. Außerdem muss man die Datei &#039;&#039;&#039;&#039;&#039;Project\STM32F4xx_StdPeriph_Templates\stm32f4xx_conf.h&#039;&#039;&#039;&#039;&#039; ebenfalls aus dem Standard-Peripheral-Library Download in den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projektes kopieren. In der IDE fügt man den Include-Path &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\inc&#039;&#039;&#039;&#039;&#039; hinzufügen, wie bei der CMSIS-Library (s.o.).&lt;br /&gt;
Außerdem muss noch &#039;&#039;&#039;&#039;&#039;USE_STDPERIPH_DRIVER&#039;&#039;&#039;&#039;&#039; als Define in der IDE hinzugefügt werden (s.o.).&lt;br /&gt;
Danach fügt man die Source- und Include-Dateien aus dem Ordner &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\inc&#039;&#039;&#039;&#039;&#039; und &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\src&#039;&#039;&#039;&#039;&#039; dem Project mit &#039;&#039;&#039;&#039;&#039;&amp;lt;Project Name&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Add files&#039;&#039;&#039;&#039;&#039; hinzu, allerdings nur die, für welche auch der Controller die entsprechende Peripherie besitzt. Beim STM32F4-Discovery Board / STM32F407VG Controller dürfen also nicht folgende Dateien nicht mit hinzugefügt werden, weil diese Peripherie nur bei anderen Controller vorhanden ist:&lt;br /&gt;
&lt;br /&gt;
*stm32f4xx_dma2d.c/.h&lt;br /&gt;
*stm32f4xx_fmc.c/.h&lt;br /&gt;
*stm32f4xx_ltdc.c/.h&lt;br /&gt;
*stm32f4xx_sai.c/.h&lt;br /&gt;
&lt;br /&gt;
Daraus resultiert folgende Struktur:&lt;br /&gt;
&lt;br /&gt;
[[Datei:stdperiphlib_2.png|Header-Struktur]] [[Datei:stdperiphlib_1.png|Source-Struktur]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Anschließen kann die Standard-Peripheral-Library benutz werden.&lt;br /&gt;
main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);&lt;br /&gt;
&lt;br /&gt;
    GPIO_InitTypeDef GPIOD_InitStructure;&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Mode = GPIO_Mode_OUT;     //Als Ausgang&lt;br /&gt;
    GPIOD_InitStructure.GPIO_OType = GPIO_OType_PP;    //Push-Pull Betrieb&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Pin = GPIO_Pin_15;        //Pin 15 (STM32F4-Discovery: Blaue LED)&lt;br /&gt;
    GPIOD_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;  //Kein Pull-Up oder Pull-Down Widerstand aktiviert&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Speed = GPIO_Speed_25MHz; //25MHz Update-Rate&lt;br /&gt;
    GPIO_Init(GPIOD, &amp;amp;GPIOD_InitStructure);&lt;br /&gt;
&lt;br /&gt;
    GPIO_SetBits(GPIOD, GPIO_Pin_15);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Einbinden der DSP-Library===&lt;br /&gt;
STM32F3 / STM32F4 Microcontroller haben neben der FPU noch einen Digital-Signal-Processor (DSP). Die DSP dient hauptsächlich dazu, viele Daten schnell zu verarbeiten (z.B. Video- oder Audiosignal). Der CMSIS-Download beinhaltet dazu neben der eigentlichen CMSIS-Library auch noch eine DSP-Library. Diese Library stellt sowohl einfache, mathematische Funktionen wie addieren, multiplizieren usw. als auch komplexe Funktionen, wie z.B  einen IIR-Filter, zur Verfügung. Die DSP-Library ist weiter aufgeteilt in kleinere Module, wie z.B. BasicMathFunctions, FilteringFunctions usw. (siehe &#039;&#039;&#039;&#039;&#039;CMSIS\DSP-Library\Source&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
Um die DSP-Library zu verwenden müssen nur die Source-Files des benötigten Moduls einbinden.&lt;br /&gt;
(&#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Add files...&#039;&#039;&#039;&#039;&#039;). Außerdem muss in der &#039;&#039;&#039;&#039;&#039;main.c&#039;&#039;&#039;&#039;&#039; der Include &#039;&#039;&#039;&#039;&#039;arm_math.h&#039;&#039;&#039;&#039;&#039; eingebunden werden. Aus irgendeinem Grund gibt es dann jedoch die Warnung: &amp;quot;Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)&amp;quot;. Ich hab noch nicht rausgefunden, wieso diese Warnung auftaucht. Die Warnung verschwindet, wenn man in der &#039;&#039;&#039;&#039;&#039;Build options...&#039;&#039;&#039;&#039;&#039; das Define &#039;&#039;&#039;&#039;&#039;__FPU_PRESENT&#039;&#039;&#039;&#039;&#039; hinzufügt (Ich weiß selber das das keine schöne Lösung ist, eine andere hab ich jedoch noch nicht gefunden). Jetzt kann die DSP-Library verwedet werden. Das Beispiel multipliziert zwei Buffer miteinander. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
#include &amp;quot;arm_math.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    float32_t x[1024];&lt;br /&gt;
    float32_t y[1024];&lt;br /&gt;
    float32_t z[1024];&lt;br /&gt;
&lt;br /&gt;
    for(uint16_t i = 0; i &amp;lt; 1024; i++)&lt;br /&gt;
    {&lt;br /&gt;
        x[i] = i;&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for(uint16_t i = 0; i &amp;lt; 1024; i++)&lt;br /&gt;
    {&lt;br /&gt;
        y[i] = PI;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    arm_mult_f32(x, y, z, 1024);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Startup-Code, Linker-Script, Takt, FPU usw.==&lt;br /&gt;
===Startup-Code===&lt;br /&gt;
Em::Blocks fügt standardmäßig einen Startup-Code mit in das Projekt ein. Die wichtigsten Dinge die darin erledigt werden sind folgende:&lt;br /&gt;
&lt;br /&gt;
*Stack und Heap wird angelgt&lt;br /&gt;
*Die Vector-Table wird angelegt&lt;br /&gt;
*Ein Default Reset-Handler wird implementiert, dieser erledigt folgende aufgaben:&lt;br /&gt;
**Kopieren der definierten Daten aus dem Flash in den SRAM&lt;br /&gt;
**&#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; wird aufgerfen, wenn &#039;&#039;&#039;&#039;&#039;__NO_SYSTEM_INIT&#039;&#039;&#039;&#039;&#039; nicht definiert ist&lt;br /&gt;
**Sprung in die &#039;&#039;&#039;&#039;&#039;main()&#039;&#039;&#039;&#039;&#039; Funktion&lt;br /&gt;
*Allen anderen Interrupt-Handler wird eine Default-Funktion &#039;&#039;&#039;&#039;&#039;def_irq_handler&#039;&#039;&#039;&#039;&#039; mit einer &#039;&#039;&#039;&#039;&#039;while(1)&#039;&#039;&#039;&#039;&#039;-Schleife zugewiesen, falls kein anderer Interrupt-Handler existiert.&lt;br /&gt;
&lt;br /&gt;
Normalerweise muss am Startup-Code nichts verändert werden.&lt;br /&gt;
&lt;br /&gt;
===Linker-Script===&lt;br /&gt;
Em::Blocks stellt zwei fertige Linker-Scripts bereit, eins für die Ausführung des Programmes aus dem Flash (&#039;&#039;&#039;&#039;&#039;*_flash.ld&#039;&#039;&#039;&#039;&#039;), das andere für die Ausführung aus dem SRAM (&#039;&#039;&#039;&#039;&#039;*_sram.ld&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Normalerweise muss auch hier nichts geändert werden, es sei den Daten sollen in bestimmten Adressbereichen abgelegt werden (z.B. im Core-Coupled RAM), was ich später noch zum Tutorial hinzufüge.&lt;br /&gt;
&lt;br /&gt;
===Der Takt===&lt;br /&gt;
Jeder Controller oder Prozessor braucht einen Takt, indem er die einzelnen Maschinen-Befehle abarbeiten kann.&lt;br /&gt;
Bei den STM32 Mikrocontrollern kann dieser Takt aus verschiedenen Quellen kommen:&lt;br /&gt;
&lt;br /&gt;
1. High Speed Internal Oszillator (HSI)&lt;br /&gt;
&lt;br /&gt;
2. High Speed External Oszillator (HSE)&lt;br /&gt;
&lt;br /&gt;
3. Low Speed Internal Oszillator (LSI)&lt;br /&gt;
&lt;br /&gt;
4. Low Speed External Oszillator (LSE)&lt;br /&gt;
&lt;br /&gt;
5. Phase-Locked Loop (PLL) (generiert den Takt aus den ersten vier Taktquellen durch Teiler und Faktoren)&lt;br /&gt;
&lt;br /&gt;
Nach einem Reset wird der Controller aus der HSI Taktquelle versorgt (16MHz beim STM32F407VG). Um die voll Performance des Controllers zu erreichen muss die PLL verwendet werden, welche den Takt durch geschickte Teiler und Faktoren vervielfältigt, sodass am Ende der Controller mit der maximalen Taktfrequenz läuft. Die notwendige Initialisierung der PLL findet in der Funktion &#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; statt. Die PLL erzeugt zunächst einen Basistakt:&lt;br /&gt;
&lt;br /&gt;
PLL_VCO = (F_HSE / PLL_M) * PLL_N&lt;br /&gt;
&lt;br /&gt;
Aus diesem Takt wird dann der Takt für den Controller-Kern abgeleitet:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = PLL_VCO / PLL_P&lt;br /&gt;
&lt;br /&gt;
Und der Takt für SDIO / USB / RNG (48MHz):&lt;br /&gt;
&lt;br /&gt;
48MHz = PLL_VCO / PLL_Q&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Durch weiter Teiler werden, die Takte für die einzelnen Busse erzeugt, da diese nicht alle beliebig schnell betrieben werden dürfen.&lt;br /&gt;
&lt;br /&gt;
Genaue Angaben findet man zu dem jeweiligen Clock-System des Controllers im Reference Manual.&lt;br /&gt;
&lt;br /&gt;
Ein Blick in den &amp;quot;Kommentar-Header&amp;quot; verrät, dass von einem externen (HSE) Oszillator von 25MHz ausgegangen wird, der die PLL versorgen soll.&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((25MHz / PLL_M(25)) * PLL_N(336)) / PLL_P(2) = 168MHz&lt;br /&gt;
&lt;br /&gt;
Allerdings stimmt diese Rechnung natürlich nur, wenn wirklich ein 25MHz Quarz am Controller angeschlossen ist. Auf dem STM32F4-Discovery Board befindet sich aber nur ein 8MHz Quarz. Demnach gilt:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((8MHz / PLL_M(25)) * PLL_N(336)) / PLL_P(2) = 53.76MHz&lt;br /&gt;
&lt;br /&gt;
Der Controller läuft also nur mit 53.76MHz, wenn wie ober beschrieben ein Projekt erstellt wird. Allerdings kann dieses Problem durch ändern von den betroffen Defines behoben werden:&lt;br /&gt;
 &lt;br /&gt;
*Dazu geht man in die &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; Datei und passt zur Vollständigkeit erstmal die zum Controller passende Tabelle im &amp;quot;Kommentar-Header&amp;quot; an (Z.57f):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      HSE Frequency(Hz)                      | 8000000&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      PLL_M                                  | 8&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Danach passt man den PPL_M Define (Z.254) an:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/************************* PLL Parameters *************************************/&lt;br /&gt;
/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */&lt;br /&gt;
#define PLL_M      8&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Außerdem muss man den HSE_VALUE Define in der &#039;&#039;&#039;&#039;&#039;inc/stm32f4xx.h&#039;&#039;&#039;&#039;&#039; angepasst werden (Z.122):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#if !defined  (HSE_VALUE)&lt;br /&gt;
  #define HSE_VALUE    ((uint32_t)8000000) /*!&amp;lt; Value of the External oscillator in Hz */&lt;br /&gt;
&lt;br /&gt;
#endif /* HSE_VALUE */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine neue Berechnung zeigt:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((8MHz / PLL_M(8)) * PLL_N(336)) / PLL_P(2) = 168MHz&lt;br /&gt;
&lt;br /&gt;
Jetzt läuft der Controller mit maximaler Geschwindigkeit.&lt;br /&gt;
&lt;br /&gt;
Die Theorie wird durch folgendes Programm verifiziert. Der geviertelte System-Takt SYSCLK wir am Pin PC9 ausgegeben. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);&lt;br /&gt;
&lt;br /&gt;
    GPIO_InitTypeDef GPIOC_InitStructure;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Mode = GPIO_Mode_AF;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_OType = GPIO_OType_PP;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Pin = GPIO_Pin_9;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;&lt;br /&gt;
    GPIO_Init(GPIOC, &amp;amp;GPIOC_InitStructure);&lt;br /&gt;
&lt;br /&gt;
    RCC_MCO2Config(RCC_MCO2Source_SYSCLK, RCC_MCO2Div_4);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Die FPU===&lt;br /&gt;
====Allgemeines====&lt;br /&gt;
Damit die FPU richtig verwendet wird, müssen normalerweise zwei Bedingungen erfüllt sein:&lt;br /&gt;
&lt;br /&gt;
1. Der Controller muss in der Initialisierung-Funktion &#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; in &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; die FPU Hardware-seitig aktivieren&lt;br /&gt;
&lt;br /&gt;
2. Damit die FPU auch was zu tuen bekommt, müssen vom Compiler FPU-Instructions erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
Die Em::Blocks IDE verwendet standardmäßig die FPU, wenn eine Vorhanden ist. Hier wird die FPU Hardware-seitig aktiviert (&#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; Z.341):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* FPU settings ------------------------------------------------------------*/&lt;br /&gt;
  #if (__FPU_PRESENT == 1) &amp;amp;&amp;amp; (__FPU_USED == 1)&lt;br /&gt;
    SCB-&amp;gt;CPACR |= ((3UL &amp;lt;&amp;lt; 10*2)|(3UL &amp;lt;&amp;lt; 11*2));  /* set CP10 and CP11 Full Access */&lt;br /&gt;
  #endif&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
__FPU_PRESENT wird in der &#039;&#039;&#039;&#039;&#039;stm32f4xx.h&#039;&#039;&#039;&#039;&#039; definiert.&lt;br /&gt;
__FPU_USED wird von der IDE übernommen (siehe Build-Log): &#039;&#039;&#039;&#039;&#039;-D__FPU_USED&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Außerdem wird der Compiler von der IDE standardmäßig mit dem Argument &#039;&#039;&#039;&#039;&#039;-mfloat-abi=hard&#039;&#039;&#039;&#039;&#039; aufgerufen, wodurch FPU-Instructions erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
====FPU abschalten====&lt;br /&gt;
Um die FPU ab zu schalten (Mir würde jetzt nur Strom sparen als Grund einfallen) geht man wie folgt vor:&lt;br /&gt;
&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick Build options -&amp;gt; Device -&amp;gt; Policy&#039;&#039;&#039;&#039;&#039; wählt man &#039;&#039;&#039;&#039;&#039;Use target settings&#039;&#039;&#039;&#039;&#039; und über nimmt die Einstellungen, die vorher dort eingetragen waren, allerdings lässt man das Feld &#039;&#039;&#039;&#039;&#039;FP-hardware&#039;&#039;&#039;&#039;&#039; frei.&lt;br /&gt;
&lt;br /&gt;
[[Datei:fpu_1.png|FPU Abschalten Schritt 1]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;Compiler Settings -&amp;gt; Policy&#039;&#039;&#039;&#039;&#039; wählt man dann &#039;&#039;&#039;&#039;&#039;Use target options only&#039;&#039;&#039;&#039;&#039;. Dann kann man unter &#039;&#039;&#039;&#039;&#039;Categories&#039;&#039;&#039;&#039;&#039; die Option &#039;&#039;&#039;&#039;&#039;ARM FPU architecture&#039;&#039;&#039;&#039;&#039; auswählen. Dort stehen dann drei Möglichkeiten für die FPU zur Verfügung:&lt;br /&gt;
&lt;br /&gt;
1. Software-FPU-Library für Gleitkomma-Berechnung verwenden - Keine FPU-Instructions werden generiert (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=soft&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
2. Eine Mischung aus Software- und Hardware-FPU wird verwendet (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=softfp&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
3. Hardware-FPU wird für Gleitkomma-Berechnungen verwendet (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=hard&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
[[Datei:fpu_2.png|FPU Abschalten Schritt 2]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Um die FPU ab zu schalten wählt man natürlich die erste Möglichkeit.&lt;br /&gt;
Bei der 2. und 3. Möglichkeit fügt die IDE auch den Define &#039;&#039;&#039;&#039;&#039;__FPU_USED&#039;&#039;&#039;&#039;&#039; hinzu. Bei Der ersten Möglichkeit nicht. Der Code muss also nicht verändert / auskommentiert werden.&lt;br /&gt;
&lt;br /&gt;
Um die FPU wieder zu aktivieren müssen alle Schritte wieder rückgängig gemacht werden.&lt;br /&gt;
&lt;br /&gt;
Am besten ist es einfach mal alle Möglichkeiten im Einzelschritt durch zu probieren. Dann stellt man schnell fest, ob die FPU aktiviert wir oder nicht. Ein Blick in den erweiterten &#039;&#039;&#039;&#039;&#039;Build-Log&#039;&#039;&#039;&#039;&#039; gibt auch schnell Aufschluss darüber, wie der Compiler aufgerufen wird (siehe Kapitel [http://www.mikrocontroller.net/articles/STM32_-_Einstieg_mit_Em::Blocks#Compilieren Compilieren]).&lt;br /&gt;
&lt;br /&gt;
====Test Programm für die FPU====&lt;br /&gt;
Hier ein kleines Testprogramm, dass misst wie viele Taktzyklen für eine Gleitkomma-Multiplikation gebraucht werden. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define CORE_SysTickEn()    (*((u32*)0xE0001000)) = 0x40000001&lt;br /&gt;
#define CORE_SysTickDis()   (*((u32*)0xE0001000)) = 0x40000000&lt;br /&gt;
#define CORE_GetSysTick()   (*((u32*)0xE0001004))&lt;br /&gt;
&lt;br /&gt;
uint32_t t1, t2, dt;&lt;br /&gt;
float x, y, z;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    x = 53.64f;&lt;br /&gt;
    y = 0.27f;&lt;br /&gt;
&lt;br /&gt;
    CORE_SysTickEn();&lt;br /&gt;
    t1 = CORE_GetSysTick();&lt;br /&gt;
&lt;br /&gt;
    z = x * y;&lt;br /&gt;
&lt;br /&gt;
    t2 = CORE_GetSysTick();&lt;br /&gt;
    CORE_SysTickDis();&lt;br /&gt;
&lt;br /&gt;
    dt = (t2 - t1) - 9; //9 Takt-Zyklen werden für die Messung gebraucht &lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Booten aus dem SRAM==&lt;br /&gt;
STM32 Controller haben die Möglichkeit Code aus dem Flash als auch aus dem SRAM auszuführen. Um eine Anwenung per Debugger in des SRAM zu laden sind nur wenige Schritte erforderlich:&lt;br /&gt;
&lt;br /&gt;
*Um das Linkerscript für den SRAM zu verwenden geht man zu: &#039;&#039;&#039;&#039;&#039;Build options... -&amp;gt; Device&#039;&#039;&#039;&#039;&#039; dort wählt man unter &#039;&#039;&#039;&#039;&#039;Policy&#039;&#039;&#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;Use target settings&#039;&#039;&#039;&#039;&#039; aus und übernimmt die vorherigen Einstellungen, nur unter &#039;&#039;&#039;&#039;&#039;Linker script*&#039;&#039;&#039;&#039;&#039; gibt man &#039;&#039;&#039;&#039;&#039;.\stm32f407vg_sram.ld&#039;&#039;&#039;&#039;&#039; an&lt;br /&gt;
&lt;br /&gt;
*Dann muss man noch unter &#039;&#039;&#039;&#039;&#039;Debug -&amp;gt; Interfaces -&amp;gt; Settings&#039;&#039;&#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;Vector table start&#039;&#039;&#039;&#039;&#039; auf 0x20000000 ändern und &#039;&#039;&#039;&#039;&#039;Execute from RAM&#039;&#039;&#039;&#039;&#039; auswählen.&lt;br /&gt;
&lt;br /&gt;
Anschließend kann man die Anwendung ganz normal debuggen. Nach einem Reset muss die Anwenung erneut mit dem Debugger gestartet werden.&lt;br /&gt;
&lt;br /&gt;
=Fortsetzung folgt..=&lt;br /&gt;
Kritik, Wünsche usw. sind gerne erwünscht, am besten hier in den Thread posten: [http://www.mikrocontroller.net/topic/323750 Neues STM32 Tutorial]&lt;br /&gt;
&lt;br /&gt;
[[Category:ARM]]&lt;br /&gt;
[[Category:STM32]]&lt;/div&gt;</summary>
		<author><name>Avrprogger</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=STM32_-_Einstieg_mit_Em::Blocks&amp;diff=81540</id>
		<title>STM32 - Einstieg mit Em::Blocks</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=STM32_-_Einstieg_mit_Em::Blocks&amp;diff=81540"/>
		<updated>2014-02-11T16:37:53Z</updated>

		<summary type="html">&lt;p&gt;Avrprogger: jhk&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In diesem Tutorial werde ich versuchen, möglichst einfach, die ersten Schritte zur Entwicklung von STM32 Anwenungen mit der Em::Blocks IDE zu erklären. Hier soll nicht so stark auf die einzelnen Peripherie-Module der Controller eingegangen werden, sondern mehr auf die IDE und die verschieden Libraries, wie die CMSIS Library, die DSP-Library, die Standard-Peripheral-Library, die USB-Library und vllt. über Ethernet. Ich denke ein Kapitel zu FreeRTOS wird es auch geben. Auserdem steht im Vordergrund Sachen wie z.B. booten aus dem SRAM, In-Application-Programming, FPU, Core-Coupled-RAM usw. Mal sehn wie weit ich komme ;)&lt;br /&gt;
&lt;br /&gt;
==Die Entwicklungsumgebung==&lt;br /&gt;
===Hardware===&lt;br /&gt;
Zum testen der Anwendungen, benutze ich das STM32F4-Discovery Board, welches einen Debugger, Peripherie und natürlich einen STM32 Controller (STM32F407VGT6) enthält. Deshalb sind alle Beispiele hier für den STM32F407VG Controller ausgelegt, können aber meisten 1:1 auf andere Controller portiert werden. Ich werde auch möglichsts keine STM32F4-Discovery Board spezifischen Libraries verwenden, damit der Portierungs-Vorgang möglichsts einfach bleibt.&lt;br /&gt;
&lt;br /&gt;
===Software===&lt;br /&gt;
In diesem Tutorial verwende ich [http://www.emblocks.org/ Em::Blocks] als IDE. Em::Blocks ist eine kostenlose, uneingeschränkte IDE, die alle STM32 Mikrcontroller unterstützt und sehr einfach zu bedienen ist.&lt;br /&gt;
nach dem Download kann die IDE per Dialog, sehr einfach, installiert werden. Als Compiler beinhaltet Em::Blocks den &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
Die IDE unterstützt zurzeit den ST-Link, den J-Link und es gibt eine Generic-Vorlage, durch welche andere Debugger konfiguriert werden können.&lt;br /&gt;
&lt;br /&gt;
Außerdem muss noch der passende Treiber für den Debugger installiert werden. Verwendet man ein Discovery-Board muss der [http://www.st.com/web/catalog/tools/FM146/CL1984/SC724/SS1677/PF251168 ST-Link/V2]-Treiber heruntergeladen und installiert werden. (Die Installation muss evtl. als Administrator ausgeführt werden, da sonst die Installation unvollständig wird.) Nach der Installation des Treibers kann man den Debugger über die entsprechende USB Schnittstelle an den PC anschließen und es sollte die Meldung von Windows kommen, dass der richtige Treiber gefunden wurde.&lt;br /&gt;
&lt;br /&gt;
===Libraries===&lt;br /&gt;
Zum programmieren benötigt man noch die [http://www.arm.com/products/processors/cortex-m/cortex-microcontroller-software-interface-standard.php CMSIS] und die Standard-Peripheral-Library (z.B. für die F4 Controller [http://www.st.com/stonline/stappl/productcatalog/app?page=partNumberSearchPage&amp;amp;levelid=SS1577&amp;amp;parentid=1743&amp;amp;resourcetype=SW Standard-Peripheral-Library-F4]), die man am besten in einen Ordner (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\STM32&#039;&#039;&#039;&#039;&#039;) entpackt&lt;br /&gt;
&lt;br /&gt;
==Basis-Wissen zur IDE==&lt;br /&gt;
Einige Grundfunktionalitäten der IDE:&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von Dateien zum Projekt===&lt;br /&gt;
Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf &amp;lt;ProjektName&amp;gt; -&amp;gt; Add files...&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Enfernen von Dateien aus dem Projekt===&lt;br /&gt;
Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf die Datei / mehrere Dateien auswählen -&amp;gt; Remove file from project&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
Die Dateien werden lediglich aus dem Projekt entfernt und nicht von der Festplatte gelöscht.&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von Include-Pfaden===&lt;br /&gt;
Sofern die Include-Datei(en) nicht im standard Include-Ordner &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; des Projektes liegen, muss man den Pfad zum Projekt hinzufügen, damit der Compiler die Include-Dateien später auch finden kann. Man geht wie folgt vor: Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf &amp;lt;ProjektName&amp;gt; -&amp;gt; Build options... -&amp;gt; Search Directories -&amp;gt; Add&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von globalen Defines zum Build===&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; #defines&#039;&#039;&#039;&#039;&#039; können globale Defines hinzugefügt werden.&lt;br /&gt;
&lt;br /&gt;
===Compilieren===&lt;br /&gt;
Entweder über das &#039;&#039;&#039;&#039;&#039;Build&#039;&#039;&#039;&#039;&#039; Menü oder über &#039;&#039;&#039;&#039;&#039;F7&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Um eine genau Ausgabe des Compiler-Aufrufes mit allen Argumenten zu bekommen, geht man im &#039;&#039;&#039;&#039;&#039;Settings&#039;&#039;&#039;&#039;&#039; Menü auf &#039;&#039;&#039;&#039;&#039;Tools...&#039;&#039;&#039;&#039;&#039; und dann auf &#039;&#039;&#039;&#039;&#039;Toolchain executables&#039;&#039;&#039;&#039;&#039;. Ganz unten, unter &#039;&#039;&#039;&#039;&#039;Logging&#039;&#039;&#039;&#039;&#039; kann man dann &#039;&#039;&#039;&#039;&#039;Full command line&#039;&#039;&#039;&#039;&#039; auswählen.&lt;br /&gt;
&lt;br /&gt;
====Compiler Optionen====&lt;br /&gt;
=====Optimierung=====&lt;br /&gt;
Standardmäßig verwendet Em::Blocks keine Optimierung. Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; Categories: Optimization&#039;&#039;&#039;&#039;&#039; kann zwischen verschieden Optimierungen ausgewählt werden.&lt;br /&gt;
&lt;br /&gt;
=====Verschiedene C-Standards=====&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; Categories: Language standard&#039;&#039;&#039;&#039;&#039; kann man zwischen verschieden C-Standard auswählen, wie z.B, C99.&lt;br /&gt;
(Mit C99 können auch die Lauf-Variable in der for-Schleife deklariert werden: for(int i;..))&lt;br /&gt;
&lt;br /&gt;
===Debuggen===&lt;br /&gt;
*Als erstes den Debugger starten über das &#039;&#039;&#039;&#039;&#039;Debug&#039;&#039;&#039;&#039;&#039; Menü und &#039;&#039;&#039;&#039;&#039;Start/stop Debug Session&#039;&#039;&#039;&#039;&#039; oder über &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
*Danach läuft die Anwendung auf dem Controller und warten im &#039;&#039;&#039;&#039;&#039;Reset_Handler&#039;&#039;&#039;&#039;&#039; auf Einzelschritt- bzw. Run- Befehle (&#039;&#039;&#039;&#039;&#039;F5, F10, F11&#039;&#039;&#039;&#039;&#039; usw..(siehe &#039;&#039;&#039;&#039;&#039;Debug-Menü&#039;&#039;&#039;&#039;&#039; für alle Möglichkeiten))&lt;br /&gt;
&lt;br /&gt;
*Mit &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039; wird die Debug-Session auch wieder beendet&lt;br /&gt;
&lt;br /&gt;
*Unter &#039;&#039;&#039;&#039;&#039;Debug -&amp;gt; Interfaces -&amp;gt; Target settings&#039;&#039;&#039;&#039;&#039; können Eigenschaften, wie z.B &#039;&#039;&#039;&#039;&#039;Run to main()&#039;&#039;&#039;&#039;&#039; aktiviert werden.&lt;br /&gt;
&lt;br /&gt;
===Projekt als Template abspeichern===&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;File -&amp;gt; Save project as template...&#039;&#039;&#039;&#039;&#039;. Das Template erscheint dann im Projekt-Dialog unter &#039;&#039;&#039;&#039;&#039;User templates&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Das erste Projekt erstellen==&lt;br /&gt;
Hier erkläre ich, wie man am Besten (aus meiner Sicht), ein neues Projekt von Grund auf erstellt, sodass man hinterher, den Controller-Kern über die CMSIS-Library und die Peripherie über die Register steuern kann.&lt;br /&gt;
&lt;br /&gt;
===1. Projekt mit der IDE erstellen===&lt;br /&gt;
Nach der Installation der oben beschriebenen Komponenten erstellt man am besten ein Verzeichnis (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\EmBlocks&#039;&#039;&#039;&#039;&#039;), indem später alle Projekte gespeichert werden. Für Libraries kann man auch noch ein Verzeichnis (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\STM32&#039;&#039;&#039;&#039;&#039;) erstellen, wo alle Libraries gespeichert werden, die man für die Projekt brauchen.&lt;br /&gt;
&lt;br /&gt;
Als nächstes starten man EmBlocks. Bei dem ersten Start öffnet sich ein Fenster, wo verschiedene Compiler angezeigt werden, die Em::Blocks findet. Dort wählt man den &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039; aus und klickt &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039;. Nun sollte sich das Hauptfenster von Em::Blocks öffnen. Über &#039;&#039;&#039;&#039;&#039;Create a new Project&#039;&#039;&#039;&#039;&#039; oder &#039;&#039;&#039;&#039;&#039;File -&amp;gt; New -&amp;gt; Project&#039;&#039;&#039;&#039;&#039; ruft man den Projekt-Dialog auf und kann ein neues Projekt erzeugen.&lt;br /&gt;
&lt;br /&gt;
Auf der Ersten Seite wählen man den &#039;&#039;&#039;&#039;&#039;STmicro-ARM&#039;&#039;&#039;&#039;&#039; Projekt-Typ aus.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_1.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auf der nächsten Seite wird man darauf hingewiesen, dass das der entsprechende Projekt-Typ-Dialog ausgeführt wird. Hier kann man ein Häkchen bei &#039;&#039;&#039;&#039;&#039;Skip this page next time&#039;&#039;&#039;&#039;&#039; setzen und auf &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; klicken.&lt;br /&gt;
&lt;br /&gt;
Im nächsten Schritt wählen man das zuvor erstellt Verzeichnis unter &#039;&#039;&#039;&#039;&#039;Folder to create Project in&#039;&#039;&#039;&#039;&#039; aus, indem später alle Projekt gespeichert werden. Außerdem geben wir dem Projekt einen Namen (z.B. &#039;&#039;&#039;&#039;&#039;FirstProject&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_2.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danach muss man einen Compiler auswählen und bestimmen, welche Projekt-Konfigurationen erszeugt werden sollen. Unter &#039;&#039;&#039;&#039;&#039;Compiler&#039;&#039;&#039;&#039;&#039; wählt man &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039; und man kann das Häkchen bei &#039;&#039;&#039;&#039;&#039;Create &amp;quot;Release&amp;quot; configuration&#039;&#039;&#039;&#039;&#039; entfernen, da diese unnötig ist, die Debug-Konfiguration sollte eig. immer ausreichen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_3.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auf den folgenden Seite wird der Controller ausgewählt. Verwendet man ein STM32F4-Discovery Board müssen folgende Dinge gewählt werden: &#039;&#039;&#039;&#039;&#039;Cortex_M4 (F3xx - F4xx) -&amp;gt; STM32F4xx (Cortex M4 with FPU) -&amp;gt; STM32F407VG&#039;&#039;&#039;&#039;&#039;. Leider sind die Auswahl Möglichkeiten nicht ganz richtig, da auch die F3 Controller einen Cortex M4 Kern und eine FPU haben (Ist aber nicht so wichtig, ist nur eine formale Sache). Außerdem entfernt man das Häkchen bei &#039;&#039;&#039;&#039;&#039;Standard Peripherals Library&#039;&#039;&#039;&#039;&#039; (Wie man die Standard-Peripheral-Library einbindet und verwendet erkläre ich später). Man kann auch das Häkchen bei &#039;&#039;&#039;&#039;&#039;Create hex file for Realease target&#039;&#039;&#039;&#039;&#039; entfernen.&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;Stack Size&#039;&#039;&#039;&#039;&#039; und &#039;&#039;&#039;&#039;&#039;Heap Size&#039;&#039;&#039;&#039;&#039; wird die Größe von Stack und Heap festgelegt. Für eine erste Anwendung kann man die Einstellungen so lassen (Stack-Size: 0x0100 =&amp;gt; 256 Byte Stack und Heap-Size: 0x0000 =&amp;gt; kein Heap). Mit &#039;&#039;&#039;&#039;&#039;Finish&#039;&#039;&#039;&#039;&#039; ist der Projekt Dialog abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_4.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danach sollten sich zwei neue Fenster öffnen, um die Debug-Eigenschaften fest zu legen.&lt;br /&gt;
Verwendet man ein Discovery Board/ST-Link müssen die Einstellungen wie auf dem Bild gewählt werden. Über den Button &#039;&#039;&#039;&#039;&#039;Settings&#039;&#039;&#039;&#039;&#039; öffnet sich das zweite Fenster, falls sich dieses nicht schon von alleine öffnen sollte. Nach den Schließen der Fenster über &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; ist der Projekt Dialog beendet und ein neues Projekt steht zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_5_1.png|Debug Eigenschaften 1. Fenster]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_5_2.png|Debug Eigenschaften 2. Fenster]]&lt;br /&gt;
&lt;br /&gt;
===2. CMSIS-Library und Startup-Code hinzufügen===&lt;br /&gt;
Wenn man sich, nachdem man ein neues Projekt in der IDE erstellt hat, die bereits vorhandenen Dateien im Projekt ansieht, stellt man fest, das bereits ein Ordner &#039;&#039;&#039;&#039;&#039;cmsis&#039;&#039;&#039;&#039;&#039; existiert, der einige wichtige Include-Dateien der CMSIS-Library enthält. Allerdings sind das wirklich nur die wichtigsten Include-Dateien der CMSIS-Library und dazu noch, die aus einer älternen Version. Ich ziehe es deshalb vor die &amp;quot;Mini-CMSIS-Libraray&amp;quot; und die &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c/.h&#039;&#039;&#039;&#039;&#039; Dateien des Projektes durch aktuellere Versionen zu ersetzen. So ist später auch die Integration  von anderen Libraries, wie z.B. der CMSIS-DSP-Libarary einfacher.  &lt;br /&gt;
&lt;br /&gt;
Zunächst gehen man in das Projekt-Verzeichnis und löscht:&lt;br /&gt;
*Den Ordner &#039;&#039;&#039;&#039;&#039;cmsis&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Alle Dateien im Include Verzeichnis &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; im &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner&lt;br /&gt;
&lt;br /&gt;
Außerdem entfernt man auch alle gelöschten Dateien in der IDE aus dem Projekt mit &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Rechts Klick -&amp;gt; Remove file from project&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Es sollte folgende Verzeichnis Struktur überbleiben:&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_6.png|Überbleibende Dateien]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Jetzt müssen die gelöschten Dateien durch die aktuelleren ersetzt werden.&lt;br /&gt;
&lt;br /&gt;
*Dazu kopieren man den gesamten Ordner &#039;&#039;&#039;&#039;&#039;CMSIS&#039;&#039;&#039;&#039;&#039; aus dem CMSIS Download in das Projekt Verzeichnis.&lt;br /&gt;
&lt;br /&gt;
*Aus dem Standard-Peripheral-Library Download kopiert man von &#039;&#039;&#039;&#039;&#039;Libraries\CMSIS\Device\ST\STM32F4xx\Include&#039;&#039;&#039;&#039;&#039; alle Dateien in den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projekt Verzeichnisses&lt;br /&gt;
&lt;br /&gt;
*Aus der Standard-Peripheral-Library kopieren man ebenfalls von &#039;&#039;&#039;&#039;&#039;Libraries\CMSIS\Device\ST\STM32F4xx\Source\Templates&#039;&#039;&#039;&#039;&#039; die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; in den &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner des Projekts&lt;br /&gt;
&lt;br /&gt;
Anschließend müssen die neuen Dateien in der IDE dem Projekt hinzugefügt werden. Dazu benutzt man &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Rechts Klick -&amp;gt; Add files&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
*Aus dem &#039;&#039;&#039;&#039;&#039;CMSIS&#039;&#039;&#039;&#039;&#039; Ordner im Projekt Verzeichnis werden aus den Unterorder &#039;&#039;&#039;&#039;&#039;Include&#039;&#039;&#039;&#039;&#039; folgende Dateien dem Projekt hinzugefügt:&lt;br /&gt;
**arm_common_tables.h&lt;br /&gt;
**arm_const_structs.h&lt;br /&gt;
**arm_math.h&lt;br /&gt;
**core_cm4.h&lt;br /&gt;
**core_cm4_simd.h&lt;br /&gt;
**core_cmFunc.h&lt;br /&gt;
**core_cmInstr.h&lt;br /&gt;
*Alle Dateien aus den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projektes&lt;br /&gt;
*Die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; aus dem &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner&lt;br /&gt;
&lt;br /&gt;
So sollte die Struktur dann aussehen:&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_7.png|Anwenungs-Grundgerüst]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Da einige Dateien der Libraries später bearbeitet werden müssen und Schreibgeschützt sind, weise ich hier schonmal darauf hin, das der Schreibschutz in der IDE über &#039;&#039;&#039;&#039;&#039;Rechts Klick auf die Datei -&amp;gt; Properties -&amp;gt; Häkchen bei &amp;quot;File is read only&amp;quot; entfernen&#039;&#039;&#039;&#039;&#039; entfert werden kann.&lt;br /&gt;
&lt;br /&gt;
Damit die IDE die Header-Dateien der CMSIS Library auch finden kann, weil diese ja nicht im standard Include Ordner &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; liegen, muss unter &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Build Options -&amp;gt; Search Directories&#039;&#039;&#039;&#039;&#039; der Pfad &#039;&#039;&#039;&#039;&#039;CMSIS\Include&#039;&#039;&#039;&#039;&#039; hinzugefügt werden.&lt;br /&gt;
&lt;br /&gt;
Compiliert man jetzt das Projekt mit &#039;&#039;&#039;&#039;&#039;F7&#039;&#039;&#039;&#039;&#039; gibt es ein paar Fehler Meldungen, weil keine Controller-Reihe ausgewählt wurde. Ebenfalls unter &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Build Options -&amp;gt; Compiler Settings -&amp;gt; #defines&#039;&#039;&#039;&#039;&#039; wird der Define &#039;&#039;&#039;&#039;&#039;STM32F40_41xxx&#039;&#039;&#039;&#039;&#039; hinzugefügt.&lt;br /&gt;
&lt;br /&gt;
Beim erneuten Compilieren sollten sich nun keine neuen Fehler ergeben.&lt;br /&gt;
&lt;br /&gt;
===Das erste Programm===&lt;br /&gt;
Nachdem ein grundsätzliches &amp;quot;Gerüst&amp;quot; fertig ist, kann man den ersten Code schreiben.&lt;br /&gt;
main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC-&amp;gt;AHB1ENR |= RCC_AHB1ENR_GPIODEN;    //Takt für GPIO aktivieren&lt;br /&gt;
    GPIOD-&amp;gt;MODER |= GPIO_MODER_MODER15_0;   //GPIOD Pin15 als Ausgang&lt;br /&gt;
    GPIOD-&amp;gt;BSRRL |= GPIO_BSRR_BS_15;        //GPIOD Pin15 auf High ziehen&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039; wird dann der Debugger gestartet. Hat der Debugger das Projekt erfolgreich übertragen kann die Ausführung mit &#039;&#039;&#039;&#039;&#039;F5&#039;&#039;&#039;&#039;&#039; begonnen werden.&lt;br /&gt;
&lt;br /&gt;
==Libraries einbinden/verwenden==&lt;br /&gt;
===Einbinden der Standard-Peripheral-Library===&lt;br /&gt;
Um nicht immer die einzelnen Register, wie im ersten &amp;quot;bare-metal&amp;quot; Beispiel, aus dem Reference-Manual zu suchen und zu beschreiben, gibt es von ST die Standard Peripheral Library, die diese Aufgaben übernimmt und mit der sich die &amp;quot;normale/grundlegende&amp;quot; (Alles außer USB und Ethernet) Peripherie recht einfach steuern lässt. Um die Library zu verwenden erzeugt man wie oben beschrieben ein neues Grundgerüst und kopiert als erstes den Ordner &#039;&#039;&#039;&#039;&#039;Libraries\STM32F4xx_StdPeriph_Driver&#039;&#039;&#039;&#039;&#039; aus dem Standard-Peripheral-Library Download in das Projekt-Verzeichnis. Außerdem muss man die Datei &#039;&#039;&#039;&#039;&#039;Project\STM32F4xx_StdPeriph_Templates\stm32f4xx_conf.h&#039;&#039;&#039;&#039;&#039; ebenfalls aus dem Standard-Peripheral-Library Download in den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projektes kopieren. In der IDE fügt man den Include-Path &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\inc&#039;&#039;&#039;&#039;&#039; hinzufügen, wie bei der CMSIS-Library (s.o.).&lt;br /&gt;
Außerdem muss noch &#039;&#039;&#039;&#039;&#039;USE_STDPERIPH_DRIVER&#039;&#039;&#039;&#039;&#039; als Define in der IDE hinzugefügt werden (s.o.).&lt;br /&gt;
Danach fügt man die Source- und Include-Dateien aus dem Ordner &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\inc&#039;&#039;&#039;&#039;&#039; und &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\src&#039;&#039;&#039;&#039;&#039; dem Project mit &#039;&#039;&#039;&#039;&#039;&amp;lt;Project Name&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Add files&#039;&#039;&#039;&#039;&#039; hinzu, allerdings nur die, für welche auch der Controller die entsprechende Peripherie besitzt. Beim STM32F4-Discovery Board / STM32F407VG Controller dürfen also nicht folgende Dateien nicht mit hinzugefügt werden, weil diese Peripherie nur bei anderen Controller vorhanden ist:&lt;br /&gt;
&lt;br /&gt;
*stm32f4xx_dma2d.c/.h&lt;br /&gt;
*stm32f4xx_fmc.c/.h&lt;br /&gt;
*stm32f4xx_ltdc.c/.h&lt;br /&gt;
*stm32f4xx_sai.c/.h&lt;br /&gt;
&lt;br /&gt;
Daraus resultiert folgende Struktur:&lt;br /&gt;
&lt;br /&gt;
[[Datei:stdperiphlib_2.png|Header-Struktur]] [[Datei:stdperiphlib_1.png|Source-Struktur]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Anschließen kann die Standard-Peripheral-Library benutz werden.&lt;br /&gt;
main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);&lt;br /&gt;
&lt;br /&gt;
    GPIO_InitTypeDef GPIOD_InitStructure;&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Mode = GPIO_Mode_OUT;     //Als Ausgang&lt;br /&gt;
    GPIOD_InitStructure.GPIO_OType = GPIO_OType_PP;    //Push-Pull Betrieb&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Pin = GPIO_Pin_15;        //Pin 15 (STM32F4-Discovery: Blaue LED)&lt;br /&gt;
    GPIOD_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;  //Kein Pull-Up oder Pull-Down Widerstand aktiviert&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Speed = GPIO_Speed_25MHz; //25MHz Update-Rate&lt;br /&gt;
    GPIO_Init(GPIOD, &amp;amp;GPIOD_InitStructure);&lt;br /&gt;
&lt;br /&gt;
    GPIO_SetBits(GPIOD, GPIO_Pin_15);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Einbinden der DSP-Library===&lt;br /&gt;
STM32F3 / STM32F4 Microcontroller haben neben der FPU noch einen Digital-Signal-Processor (DSP). Die DSP dient hauptsächlich dazu, viele Daten schnell zu verarbeiten (z.B. Video- oder Audiosignal). Der CMSIS-Download beinhaltet dazu neben der eigentlichen CMSIS-Library auch noch eine DSP-Library. Diese Library stellt sowohl einfache, mathematische Funktionen wie addieren, multiplizieren usw. als auch komplexe Funktionen, wie z.B  einen IIR-Filter, zur Verfügung. Die DSP-Library ist weiter aufgeteilt in kleinere Module, wie z.B. BasicMathFunctions, FilteringFunctions usw. (siehe &#039;&#039;&#039;&#039;&#039;CMSIS\DSP-Library\Source&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
Um die DSP-Library zu verwenden müssen nur die Source-Files des benötigten Moduls einbinden.&lt;br /&gt;
(&#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Add files...&#039;&#039;&#039;&#039;&#039;). Außerdem muss in der &#039;&#039;&#039;&#039;&#039;main.c&#039;&#039;&#039;&#039;&#039; der Include &#039;&#039;&#039;&#039;&#039;arm_math.h&#039;&#039;&#039;&#039;&#039; eingebunden werden. Aus irgendeinem Grund gibt es dann jedoch die Warnung: &amp;quot;Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)&amp;quot;. Ich hab noch nicht rausgefunden, wieso diese Warnung auftaucht. Die Warnung verschwindet, wenn man in der &#039;&#039;&#039;&#039;&#039;Build options...&#039;&#039;&#039;&#039;&#039; das Define &#039;&#039;&#039;&#039;&#039;__FPU_PRESENT&#039;&#039;&#039;&#039;&#039; hinzufügt (Ich weiß selber das das keine schöne Lösung ist, eine andere hab ich jedoch noch nicht gefunden). Jetzt kann die DSP-Library verwedet werden. Das Beispiel multipliziert zwei Buffer miteinander. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
#include &amp;quot;arm_math.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    float32_t x[1024];&lt;br /&gt;
    float32_t y[1024];&lt;br /&gt;
    float32_t z[1024];&lt;br /&gt;
&lt;br /&gt;
    for(uint16_t i = 0; i &amp;lt; 1024; i++)&lt;br /&gt;
    {&lt;br /&gt;
        x[i] = i;&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for(uint16_t i = 0; i &amp;lt; 1024; i++)&lt;br /&gt;
    {&lt;br /&gt;
        y[i] = PI;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    arm_mult_f32(x, y, z, 1024);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Startup-Code, Linker-Script, Takt, FPU, Optimierung usw.==&lt;br /&gt;
===Startup-Code===&lt;br /&gt;
Em::Blocks fügt standardmäßig einen Startup-Code mit in das Projekt ein. Die wichtigsten Dinge die darin erledigt werden sind folgende:&lt;br /&gt;
&lt;br /&gt;
*Stack und Heap wird angelgt&lt;br /&gt;
*Die Vector-Table wird angelegt&lt;br /&gt;
*Ein Default Reset-Handler wird implementiert, dieser erledigt folgende aufgaben:&lt;br /&gt;
**Kopieren der definierten Daten aus dem Flash in den SRAM&lt;br /&gt;
**&#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; wird aufgerfen, wenn &#039;&#039;&#039;&#039;&#039;__NO_SYSTEM_INIT&#039;&#039;&#039;&#039;&#039; nicht definiert ist&lt;br /&gt;
**Sprung in die &#039;&#039;&#039;&#039;&#039;main()&#039;&#039;&#039;&#039;&#039; Funktion&lt;br /&gt;
*Allen anderen Interrupt-Handler wird eine Default-Funktion &#039;&#039;&#039;&#039;&#039;def_irq_handler&#039;&#039;&#039;&#039;&#039; mit einer &#039;&#039;&#039;&#039;&#039;while(1)&#039;&#039;&#039;&#039;&#039;-Schleife zugewiesen, falls kein anderer Interrupt-Handler existiert.&lt;br /&gt;
&lt;br /&gt;
Normalerweise muss am Startup-Code nichts verändert werden.&lt;br /&gt;
&lt;br /&gt;
===Linker-Script===&lt;br /&gt;
Em::Blocks stellt zwei fertige Linker-Scripts bereit, eins für die Ausführung des Programmes aus dem Flash (&#039;&#039;&#039;&#039;&#039;*_flash.ld&#039;&#039;&#039;&#039;&#039;), das andere für die Ausführung aus dem SRAM (&#039;&#039;&#039;&#039;&#039;*_sram.ld&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Normalerweise muss auch hier nichts geändert werden, es sei den Daten sollen in bestimmten Adressbereichen abgelegt werden (z.B. im Core-Coupled RAM), was ich später noch zum Tutorial hinzufüge.&lt;br /&gt;
&lt;br /&gt;
===Der Takt===&lt;br /&gt;
Jeder Controller oder Prozessor braucht einen Takt, indem er die einzelnen Maschinen-Befehle abarbeiten kann.&lt;br /&gt;
Bei den STM32 Mikrocontrollern kann dieser Takt aus verschiedenen Quellen kommen:&lt;br /&gt;
&lt;br /&gt;
1. High Speed Internal Oszillator (HSI)&lt;br /&gt;
&lt;br /&gt;
2. High Speed External Oszillator (HSE)&lt;br /&gt;
&lt;br /&gt;
3. Low Speed Internal Oszillator (LSI)&lt;br /&gt;
&lt;br /&gt;
4. Low Speed External Oszillator (LSE)&lt;br /&gt;
&lt;br /&gt;
5. Phase-Locked Loop (PLL) (generiert den Takt aus den ersten vier Taktquellen durch Teiler und Faktoren)&lt;br /&gt;
&lt;br /&gt;
Nach einem Reset wird der Controller aus der HSI Taktquelle versorgt (16MHz beim STM32F407VG). Um die voll Performance des Controllers zu erreichen muss die PLL verwendet werden, welche den Takt durch geschickte Teiler und Faktoren vervielfältigt, sodass am Ende der Controller mit der maximalen Taktfrequenz läuft. Die notwendige Initialisierung der PLL findet in der Funktion &#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; statt. Die PLL erzeugt zunächst einen Basistakt:&lt;br /&gt;
&lt;br /&gt;
PLL_VCO = (F_HSE / PLL_M) * PLL_N&lt;br /&gt;
&lt;br /&gt;
Aus diesem Takt wird dann der Takt für den Controller-Kern abgeleitet:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = PLL_VCO / PLL_P&lt;br /&gt;
&lt;br /&gt;
Und der Takt für SDIO / USB / RNG (48MHz):&lt;br /&gt;
&lt;br /&gt;
48MHz = PLL_VCO / PLL_Q&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Durch weiter Teiler werden, die Takte für die einzelnen Busse erzeugt, da diese nicht alle beliebig schnell betrieben werden dürfen.&lt;br /&gt;
&lt;br /&gt;
Genaue Angaben findet man zu dem jeweiligen Clock-System des Controllers im Reference Manual.&lt;br /&gt;
&lt;br /&gt;
Ein Blick in den &amp;quot;Kommentar-Header&amp;quot; verrät, dass von einem externen (HSE) Oszillator von 25MHz ausgegangen wird, der die PLL versorgen soll.&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((25MHz / PLL_M(25)) * PLL_N(336)) / PLL_P(2) = 168MHz&lt;br /&gt;
&lt;br /&gt;
Allerdings stimmt diese Rechnung natürlich nur, wenn wirklich ein 25MHz Quarz am Controller angeschlossen ist. Auf dem STM32F4-Discovery Board befindet sich aber nur ein 8MHz Quarz. Demnach gilt:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((8MHz / PLL_M(25)) * PLL_N(336)) / PLL_P(2) = 53.76MHz&lt;br /&gt;
&lt;br /&gt;
Der Controller läuft also nur mit 53.76MHz, wenn wie ober beschrieben ein Projekt erstellt wird. Allerdings kann dieses Problem durch ändern von den betroffen Defines behoben werden:&lt;br /&gt;
 &lt;br /&gt;
*Dazu geht man in die &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; Datei und passt zur Vollständigkeit erstmal die zum Controller passende Tabelle im &amp;quot;Kommentar-Header&amp;quot; an (Z.57f):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      HSE Frequency(Hz)                      | 8000000&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      PLL_M                                  | 8&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Danach passt man den PPL_M Define (Z.254) an:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/************************* PLL Parameters *************************************/&lt;br /&gt;
/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */&lt;br /&gt;
#define PLL_M      8&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Außerdem muss man den HSE_VALUE Define in der &#039;&#039;&#039;&#039;&#039;inc/stm32f4xx.h&#039;&#039;&#039;&#039;&#039; angepasst werden (Z.122):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#if !defined  (HSE_VALUE)&lt;br /&gt;
  #define HSE_VALUE    ((uint32_t)8000000) /*!&amp;lt; Value of the External oscillator in Hz */&lt;br /&gt;
&lt;br /&gt;
#endif /* HSE_VALUE */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine neue Berechnung zeigt:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((8MHz / PLL_M(8)) * PLL_N(336)) / PLL_P(2) = 168MHz&lt;br /&gt;
&lt;br /&gt;
Jetzt läuft der Controller mit maximaler Geschwindigkeit.&lt;br /&gt;
&lt;br /&gt;
Die Theorie wird durch folgendes Programm verifiziert. Der geviertelte System-Takt SYSCLK wir am Pin PC9 ausgegeben. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);&lt;br /&gt;
&lt;br /&gt;
    GPIO_InitTypeDef GPIOC_InitStructure;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Mode = GPIO_Mode_AF;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_OType = GPIO_OType_PP;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Pin = GPIO_Pin_9;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;&lt;br /&gt;
    GPIO_Init(GPIOC, &amp;amp;GPIOC_InitStructure);&lt;br /&gt;
&lt;br /&gt;
    RCC_MCO2Config(RCC_MCO2Source_SYSCLK, RCC_MCO2Div_4);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Die FPU===&lt;br /&gt;
====Allgemeines====&lt;br /&gt;
Damit die FPU richtig verwendet wird, müssen normalerweise zwei Bedingungen erfüllt sein:&lt;br /&gt;
&lt;br /&gt;
1. Der Controller muss in der Initialisierung-Funktion &#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; in &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; die FPU Hardware-seitig aktivieren&lt;br /&gt;
&lt;br /&gt;
2. Damit die FPU auch was zu tuen bekommt, müssen vom Compiler FPU-Instructions erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
Die Em::Blocks IDE verwendet standardmäßig die FPU, wenn eine Vorhanden ist. Hier wird die FPU Hardware-seitig aktiviert (&#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; Z.341):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* FPU settings ------------------------------------------------------------*/&lt;br /&gt;
  #if (__FPU_PRESENT == 1) &amp;amp;&amp;amp; (__FPU_USED == 1)&lt;br /&gt;
    SCB-&amp;gt;CPACR |= ((3UL &amp;lt;&amp;lt; 10*2)|(3UL &amp;lt;&amp;lt; 11*2));  /* set CP10 and CP11 Full Access */&lt;br /&gt;
  #endif&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
__FPU_PRESENT wird in der &#039;&#039;&#039;&#039;&#039;stm32f4xx.h&#039;&#039;&#039;&#039;&#039; definiert.&lt;br /&gt;
__FPU_USED wird von der IDE übernommen (siehe Build-Log): &#039;&#039;&#039;&#039;&#039;-D__FPU_USED&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Außerdem wird der Compiler von der IDE standardmäßig mit dem Argument &#039;&#039;&#039;&#039;&#039;-mfloat-abi=hard&#039;&#039;&#039;&#039;&#039; aufgerufen, wodurch FPU-Instructions erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
====FPU abschalten====&lt;br /&gt;
Um die FPU ab zu schalten (Mir würde jetzt nur Strom sparen als Grund einfallen) geht man wie folgt vor:&lt;br /&gt;
&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick Build options -&amp;gt; Device -&amp;gt; Policy&#039;&#039;&#039;&#039;&#039; wählt man &#039;&#039;&#039;&#039;&#039;Use target settings&#039;&#039;&#039;&#039;&#039; und über nimmt die Einstellungen, die vorher dort eingetragen waren, allerdings lässt man das Feld &#039;&#039;&#039;&#039;&#039;FP-hardware&#039;&#039;&#039;&#039;&#039; frei.&lt;br /&gt;
&lt;br /&gt;
[[Datei:fpu_1.png|FPU Abschalten Schritt 1]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;Compiler Settings -&amp;gt; Policy&#039;&#039;&#039;&#039;&#039; wählt man dann &#039;&#039;&#039;&#039;&#039;Use target options only&#039;&#039;&#039;&#039;&#039;. Dann kann man unter &#039;&#039;&#039;&#039;&#039;Categories&#039;&#039;&#039;&#039;&#039; die Option &#039;&#039;&#039;&#039;&#039;ARM FPU architecture&#039;&#039;&#039;&#039;&#039; auswählen. Dort stehen dann drei Möglichkeiten für die FPU zur Verfügung:&lt;br /&gt;
&lt;br /&gt;
1. Software-FPU-Library für Gleitkomma-Berechnung verwenden - Keine FPU-Instructions werden generiert (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=soft&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
2. Eine Mischung aus Software- und Hardware-FPU wird verwendet (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=softfp&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
3. Hardware-FPU wird für Gleitkomma-Berechnungen verwendet (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=hard&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
[[Datei:fpu_2.png|FPU Abschalten Schritt 2]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Um die FPU ab zu schalten wählt man natürlich die erste Möglichkeit.&lt;br /&gt;
Bei der 2. und 3. Möglichkeit fügt die IDE auch den Define &#039;&#039;&#039;&#039;&#039;__FPU_USED&#039;&#039;&#039;&#039;&#039; hinzu. Bei Der ersten Möglichkeit nicht. Der Code muss also nicht verändert / auskommentiert werden.&lt;br /&gt;
&lt;br /&gt;
Um die FPU wieder zu aktivieren müssen alle Schritte wieder rückgängig gemacht werden.&lt;br /&gt;
&lt;br /&gt;
Am besten ist es einfach mal alle Möglichkeiten im Einzelschritt durch zu probieren. Dann stellt man schnell fest, ob die FPU aktiviert wir oder nicht. Ein Blick in den erweiterten &#039;&#039;&#039;&#039;&#039;Build-Log&#039;&#039;&#039;&#039;&#039; gibt auch schnell Aufschluss darüber, wie der Compiler aufgerufen wird (siehe Kapitel [http://www.mikrocontroller.net/articles/STM32_-_Einstieg_mit_Em::Blocks#Compilieren Compilieren]).&lt;br /&gt;
&lt;br /&gt;
====Test Programm für die FPU====&lt;br /&gt;
Hier ein kleines Testprogramm, dass misst wie viele Taktzyklen für eine Gleitkomma-Multiplikation gebraucht werden. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define CORE_SysTickEn()    (*((u32*)0xE0001000)) = 0x40000001&lt;br /&gt;
#define CORE_SysTickDis()   (*((u32*)0xE0001000)) = 0x40000000&lt;br /&gt;
#define CORE_GetSysTick()   (*((u32*)0xE0001004))&lt;br /&gt;
&lt;br /&gt;
uint32_t t1, t2, dt;&lt;br /&gt;
float x, y, z;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    x = 53.64f;&lt;br /&gt;
    y = 0.27f;&lt;br /&gt;
&lt;br /&gt;
    CORE_SysTickEn();&lt;br /&gt;
    t1 = CORE_GetSysTick();&lt;br /&gt;
&lt;br /&gt;
    z = x * y;&lt;br /&gt;
&lt;br /&gt;
    t2 = CORE_GetSysTick();&lt;br /&gt;
    CORE_SysTickDis();&lt;br /&gt;
&lt;br /&gt;
    dt = (t2 - t1) - 9; //9 Takt-Zyklen werden für die Messung gebraucht &lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Booten aus dem SRAM==&lt;br /&gt;
STM32 Controller haben die Möglichkeit Code aus dem Flash als auch aus dem SRAM auszuführen. Um eine Anwenung per Debugger in des SRAM zu laden sind nur wenige Schritte erforderlich:&lt;br /&gt;
&lt;br /&gt;
*Um das Linkerscript für den SRAM zu verwenden geht man zu: &#039;&#039;&#039;&#039;&#039;Build options... -&amp;gt; Device&#039;&#039;&#039;&#039;&#039; dort wählt man unter &#039;&#039;&#039;&#039;&#039;Policy&#039;&#039;&#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;Use target settings&#039;&#039;&#039;&#039;&#039; aus und übernimmt die vorherigen Einstellungen, nur unter &#039;&#039;&#039;&#039;&#039;Linker script*&#039;&#039;&#039;&#039;&#039; gibt man &#039;&#039;&#039;&#039;&#039;.\stm32f407vg_sram.ld&#039;&#039;&#039;&#039;&#039; an&lt;br /&gt;
&lt;br /&gt;
*Dann muss man noch unter &#039;&#039;&#039;&#039;&#039;Debug -&amp;gt; Interfaces -&amp;gt; Settings&#039;&#039;&#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;Vector table start&#039;&#039;&#039;&#039;&#039; auf 0x20000000 ändern und &#039;&#039;&#039;&#039;&#039;Execute from RAM&#039;&#039;&#039;&#039;&#039; auswählen.&lt;br /&gt;
&lt;br /&gt;
Anschließend kann man die Anwendung ganz normal debuggen. Nach einem Reset muss die Anwenung erneut mit dem Debugger gestartet werden.&lt;br /&gt;
&lt;br /&gt;
=Fortsetzung folgt..=&lt;br /&gt;
Kritik, Wünsche usw. sind gerne erwünscht, am besten hier in den Thread posten: [http://www.mikrocontroller.net/topic/323750 Neues STM32 Tutorial]&lt;br /&gt;
&lt;br /&gt;
[[Category:ARM]]&lt;br /&gt;
[[Category:STM32]]&lt;/div&gt;</summary>
		<author><name>Avrprogger</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=STM32_-_Einstieg_mit_Em::Blocks&amp;diff=81539</id>
		<title>STM32 - Einstieg mit Em::Blocks</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=STM32_-_Einstieg_mit_Em::Blocks&amp;diff=81539"/>
		<updated>2014-02-11T16:37:20Z</updated>

		<summary type="html">&lt;p&gt;Avrprogger: cvb&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In diesem Tutorial werde ich versuchen, möglichst einfach, die ersten Schritte zur Entwicklung von STM32 Anwenungen mit der Em::Blocks IDE zu erklären. Hier soll nicht so stark auf die einzelnen Peripherie-Module der Controller eingegangen werden, sondern mehr auf die IDE und die verschieden Libraries, wie die CMSIS Library, die DSP-Library, die Standard-Peripheral-Library, die USB-Library und vllt. über Ethernet. Ich denke ein Kapitel zu FreeRTOS wird es auch geben. Auserdem steht im Vordergrund Sachen wie z.B. booten aus dem SRAM, In-Application-Programming, FPU, Core-Coupled-RAM usw. Mal sehn wie weit ich komme ;)&lt;br /&gt;
&lt;br /&gt;
==Die Entwicklungsumgebung==&lt;br /&gt;
===Hardware===&lt;br /&gt;
Zum testen der Anwendungen, benutze ich das STM32F4-Discovery Board, welches einen Debugger, Peripherie und natürlich einen STM32 Controller (STM32F407VGT6) enthält. Deshalb sind alle Beispiele hier für den STM32F407VG Controller ausgelegt, können aber meisten 1:1 auf andere Controller portiert werden. Ich werde auch möglichsts keine STM32F4-Discovery Board spezifischen Libraries verwenden, damit der Portierungs-Vorgang möglichsts einfach bleibt.&lt;br /&gt;
&lt;br /&gt;
===Software===&lt;br /&gt;
In diesem Tutorial verwende ich [http://www.emblocks.org/ Em::Blocks] als IDE. Em::Blocks ist eine kostenlose, uneingeschränkte IDE, die alle STM32 Mikrcontroller unterstützt und sehr einfach zu bedienen ist.&lt;br /&gt;
nach dem Download kann die IDE per Dialog, sehr einfach, installiert werden. Als Compiler beinhaltet Em::Blocks den &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
Die IDE unterstützt zurzeit den ST-Link, den J-Link und es gibt eine Generic-Vorlage, durch welche andere Debugger konfiguriert werden können.&lt;br /&gt;
&lt;br /&gt;
Außerdem muss noch der passende Treiber für den Debugger installiert werden. Verwendet man ein Discovery-Board muss der [http://www.st.com/web/catalog/tools/FM146/CL1984/SC724/SS1677/PF251168 ST-Link/V2]-Treiber heruntergeladen und installiert werden. (Die Installation muss evtl. als Administrator ausgeführt werden, da sonst die Installation unvollständig wird.) Nach der Installation des Treibers kann man den Debugger über die entsprechende USB Schnittstelle an den PC anschließen und es sollte die Meldung von Windows kommen, dass der richtige Treiber gefunden wurde.&lt;br /&gt;
&lt;br /&gt;
===Libraries===&lt;br /&gt;
Zum programmieren benötigt man noch die [http://www.arm.com/products/processors/cortex-m/cortex-microcontroller-software-interface-standard.php CMSIS] und die Standard-Peripheral-Library (z.B. für die F4 Controller [http://www.st.com/stonline/stappl/productcatalog/app?page=partNumberSearchPage&amp;amp;levelid=SS1577&amp;amp;parentid=1743&amp;amp;resourcetype=SW Standard-Peripheral-Library-F4]), die man am besten in einen Ordner (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\STM32&#039;&#039;&#039;&#039;&#039;) entpackt&lt;br /&gt;
&lt;br /&gt;
==Basis-Wissen zur IDE==&lt;br /&gt;
Einige Grundfunktionalitäten der IDE:&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von Dateien zum Projekt===&lt;br /&gt;
Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf &amp;lt;ProjektName&amp;gt; -&amp;gt; Add files...&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Enfernen von Dateien aus dem Projekt===&lt;br /&gt;
Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf die Datei / mehrere Dateien auswählen -&amp;gt; Remove file from project&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
Die Dateien werden lediglich aus dem Projekt entfernt und nicht von der Festplatte gelöscht.&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von Include-Pfaden===&lt;br /&gt;
Sofern die Include-Datei(en) nicht im standard Include-Ordner &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; des Projektes liegen, muss man den Pfad zum Projekt hinzufügen, damit der Compiler die Include-Dateien später auch finden kann. Man geht wie folgt vor: Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf &amp;lt;ProjektName&amp;gt; -&amp;gt; Build options... -&amp;gt; Search Directories -&amp;gt; Add&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von globalen Defines zum Build===&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; #defines&#039;&#039;&#039;&#039;&#039; können globale Defines hinzugefügt werden.&lt;br /&gt;
&lt;br /&gt;
===Compilieren===&lt;br /&gt;
Entweder über das &#039;&#039;&#039;&#039;&#039;Build&#039;&#039;&#039;&#039;&#039; Menü oder über &#039;&#039;&#039;&#039;&#039;F7&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Um eine genau Ausgabe des Compiler-Aufrufes mit allen Argumenten zu bekommen, geht man im &#039;&#039;&#039;&#039;&#039;Settings&#039;&#039;&#039;&#039;&#039; Menü auf &#039;&#039;&#039;&#039;&#039;Tools...&#039;&#039;&#039;&#039;&#039; und dann auf &#039;&#039;&#039;&#039;&#039;Toolchain executables&#039;&#039;&#039;&#039;&#039;. Ganz unten, unter &#039;&#039;&#039;&#039;&#039;Logging&#039;&#039;&#039;&#039;&#039; kann man dann &#039;&#039;&#039;&#039;&#039;Full command line&#039;&#039;&#039;&#039;&#039; auswählen.&lt;br /&gt;
&lt;br /&gt;
====Compiler Optionen====&lt;br /&gt;
=====Optimierung=====&lt;br /&gt;
Standardmäßig verwendet Em::Blocks keine Optimierung. Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; Categories: Optimization&#039;&#039;&#039;&#039;&#039; kann zwischen verschieden Optimierungen ausgewählt werden.&lt;br /&gt;
&lt;br /&gt;
=====Verschiedene C-Standards=====&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; Categories: Language standard&#039;&#039;&#039;&#039;&#039; kann man zwischen verschieden C-Standard auswählen, wie z.B, C99.&lt;br /&gt;
(Mit C99 können auch die Lauf-Variable in der for-Schleife deklariert werden: for(int i;..))&lt;br /&gt;
&lt;br /&gt;
===Debuggen===&lt;br /&gt;
*Als erstes den Debugger starten über das &#039;&#039;&#039;&#039;&#039;Debug&#039;&#039;&#039;&#039;&#039; Menü und &#039;&#039;&#039;&#039;&#039;Start/stop Debug Session&#039;&#039;&#039;&#039;&#039; oder über &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
*Danach läuft die Anwendung auf dem Controller und warten im &#039;&#039;&#039;&#039;&#039;Reset_Handler&#039;&#039;&#039;&#039;&#039; auf Einzelschritt- bzw. Run- Befehle (&#039;&#039;&#039;&#039;&#039;F5, F10, F11&#039;&#039;&#039;&#039;&#039; usw..(siehe &#039;&#039;&#039;&#039;&#039;Debug-Menü&#039;&#039;&#039;&#039;&#039; für alle Möglichkeiten))&lt;br /&gt;
&lt;br /&gt;
*Mit &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039; wird die Debug-Session auch wieder beendet&lt;br /&gt;
&lt;br /&gt;
*Unter &#039;&#039;&#039;&#039;&#039;Debug -&amp;gt; Interfaces -&amp;gt; Target settings&#039;&#039;&#039;&#039;&#039; können Eigenschaften, wie z.B &#039;&#039;&#039;&#039;&#039;Run to main()&#039;&#039;&#039;&#039;&#039; aktiviert werden.&lt;br /&gt;
&lt;br /&gt;
===Projekt als Template abspeichern===&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;File -&amp;gt; Save project as template...&#039;&#039;&#039;&#039;&#039;. Das Template erscheint dann im Projekt-Dialog unter &#039;&#039;&#039;&#039;&#039;User templates&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Das erste Projekt erstellen==&lt;br /&gt;
Hier erkläre ich, wie man am Besten (aus meiner Sicht), ein neues Projekt von Grund auf erstellt, sodass man hinterher, den Controller-Kern über die CMSIS-Library und die Peripherie über die Register steuern kann.&lt;br /&gt;
&lt;br /&gt;
===1. Projekt mit der IDE erstellen===&lt;br /&gt;
Nach der Installation der oben beschriebenen Komponenten erstellt man am besten ein Verzeichnis (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\EmBlocks&#039;&#039;&#039;&#039;&#039;), indem später alle Projekte gespeichert werden. Für Libraries kann man auch noch ein Verzeichnis (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\STM32&#039;&#039;&#039;&#039;&#039;) erstellen, wo alle Libraries gespeichert werden, die man für die Projekt brauchen.&lt;br /&gt;
&lt;br /&gt;
Als nächstes starten man EmBlocks. Bei dem ersten Start öffnet sich ein Fenster, wo verschiedene Compiler angezeigt werden, die Em::Blocks findet. Dort wählt man den &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039; aus und klickt &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039;. Nun sollte sich das Hauptfenster von Em::Blocks öffnen. Über &#039;&#039;&#039;&#039;&#039;Create a new Project&#039;&#039;&#039;&#039;&#039; oder &#039;&#039;&#039;&#039;&#039;File -&amp;gt; New -&amp;gt; Project&#039;&#039;&#039;&#039;&#039; ruft man den Projekt-Dialog auf und kann ein neues Projekt erzeugen.&lt;br /&gt;
&lt;br /&gt;
Auf der Ersten Seite wählen man den &#039;&#039;&#039;&#039;&#039;STmicro-ARM&#039;&#039;&#039;&#039;&#039; Projekt-Typ aus.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_1.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auf der nächsten Seite wird man darauf hingewiesen, dass das der entsprechende Projekt-Typ-Dialog ausgeführt wird. Hier kann man ein Häkchen bei &#039;&#039;&#039;&#039;&#039;Skip this page next time&#039;&#039;&#039;&#039;&#039; setzen und auf &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; klicken.&lt;br /&gt;
&lt;br /&gt;
Im nächsten Schritt wählen man das zuvor erstellt Verzeichnis unter &#039;&#039;&#039;&#039;&#039;Folder to create Project in&#039;&#039;&#039;&#039;&#039; aus, indem später alle Projekt gespeichert werden. Außerdem geben wir dem Projekt einen Namen (z.B. &#039;&#039;&#039;&#039;&#039;FirstProject&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_2.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danach muss man einen Compiler auswählen und bestimmen, welche Projekt-Konfigurationen erszeugt werden sollen. Unter &#039;&#039;&#039;&#039;&#039;Compiler&#039;&#039;&#039;&#039;&#039; wählt man &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039; und man kann das Häkchen bei &#039;&#039;&#039;&#039;&#039;Create &amp;quot;Release&amp;quot; configuration&#039;&#039;&#039;&#039;&#039; entfernen, da diese unnötig ist, die Debug-Konfiguration sollte eig. immer ausreichen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_3.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auf den folgenden Seite wird der Controller ausgewählt. Verwendet man ein STM32F4-Discovery Board müssen folgende Dinge gewählt werden: &#039;&#039;&#039;&#039;&#039;Cortex_M4 (F3xx - F4xx) -&amp;gt; STM32F4xx (Cortex M4 with FPU) -&amp;gt; STM32F407VG&#039;&#039;&#039;&#039;&#039;. Leider sind die Auswahl Möglichkeiten nicht ganz richtig, da auch die F3 Controller einen Cortex M4 Kern und eine FPU haben (Ist aber nicht so wichtig, ist nur eine formale Sache). Außerdem entfernt man das Häkchen bei &#039;&#039;&#039;&#039;&#039;Standard Peripherals Library&#039;&#039;&#039;&#039;&#039; (Wie man die Standard-Peripheral-Library einbindet und verwendet erkläre ich später). Man kann auch das Häkchen bei &#039;&#039;&#039;&#039;&#039;Create hex file for Realease target&#039;&#039;&#039;&#039;&#039; entfernen.&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;Stack Size&#039;&#039;&#039;&#039;&#039; und &#039;&#039;&#039;&#039;&#039;Heap Size&#039;&#039;&#039;&#039;&#039; wird die Größe von Stack und Heap festgelegt. Für eine erste Anwendung kann man die Einstellungen so lassen (Stack-Size: 0x0100 =&amp;gt; 256 Byte Stack und Heap-Size: 0x0000 =&amp;gt; kein Heap). Mit &#039;&#039;&#039;&#039;&#039;Finish&#039;&#039;&#039;&#039;&#039; ist der Projekt Dialog abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_4.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danach sollten sich zwei neue Fenster öffnen, um die Debug-Eigenschaften fest zu legen.&lt;br /&gt;
Verwendet man ein Discovery Board/ST-Link müssen die Einstellungen wie auf dem Bild gewählt werden. Über den Button &#039;&#039;&#039;&#039;&#039;Settings&#039;&#039;&#039;&#039;&#039; öffnet sich das zweite Fenster, falls sich dieses nicht schon von alleine öffnen sollte. Nach den Schließen der Fenster über &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; ist der Projekt Dialog beendet und ein neues Projekt steht zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_5_1.png|Debug Eigenschaften 1. Fenster]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_5_2.png|Debug Eigenschaften 2. Fenster]]&lt;br /&gt;
&lt;br /&gt;
===2. CMSIS-Library und Startup-Code hinzufügen===&lt;br /&gt;
Wenn man sich, nachdem man ein neues Projekt in der IDE erstellt hat, die bereits vorhandenen Dateien im Projekt ansieht, stellt man fest, das bereits ein Ordner &#039;&#039;&#039;&#039;&#039;cmsis&#039;&#039;&#039;&#039;&#039; existiert, der einige wichtige Include-Dateien der CMSIS-Library enthält. Allerdings sind das wirklich nur die wichtigsten Include-Dateien der CMSIS-Library und dazu noch, die aus einer älternen Version. Ich ziehe es deshalb vor die &amp;quot;Mini-CMSIS-Libraray&amp;quot; und die &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c/.h&#039;&#039;&#039;&#039;&#039; Dateien des Projektes durch aktuellere Versionen zu ersetzen. So ist später auch die Integration  von anderen Libraries, wie z.B. der CMSIS-DSP-Libarary einfacher.  &lt;br /&gt;
&lt;br /&gt;
Zunächst gehen man in das Projekt-Verzeichnis und löscht:&lt;br /&gt;
*Den Ordner &#039;&#039;&#039;&#039;&#039;cmsis&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Alle Dateien im Include Verzeichnis &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; im &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner&lt;br /&gt;
&lt;br /&gt;
Außerdem entfernt man auch alle gelöschten Dateien in der IDE aus dem Projekt mit &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Rechts Klick -&amp;gt; Remove file from project&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Es sollte folgende Verzeichnis Struktur überbleiben:&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_6.png|Überbleibende Dateien]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Jetzt müssen die gelöschten Dateien durch die aktuelleren ersetzt werden.&lt;br /&gt;
&lt;br /&gt;
*Dazu kopieren man den gesamten Ordner &#039;&#039;&#039;&#039;&#039;CMSIS&#039;&#039;&#039;&#039;&#039; aus dem CMSIS Download in das Projekt Verzeichnis.&lt;br /&gt;
&lt;br /&gt;
*Aus dem Standard-Peripheral-Library Download kopiert man von &#039;&#039;&#039;&#039;&#039;Libraries\CMSIS\Device\ST\STM32F4xx\Include&#039;&#039;&#039;&#039;&#039; alle Dateien in den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projekt Verzeichnisses&lt;br /&gt;
&lt;br /&gt;
*Aus der Standard-Peripheral-Library kopieren man ebenfalls von &#039;&#039;&#039;&#039;&#039;Libraries\CMSIS\Device\ST\STM32F4xx\Source\Templates&#039;&#039;&#039;&#039;&#039; die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; in den &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner des Projekts&lt;br /&gt;
&lt;br /&gt;
Anschließend müssen die neuen Dateien in der IDE dem Projekt hinzugefügt werden. Dazu benutzt man &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Rechts Klick -&amp;gt; Add files&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
*Aus dem &#039;&#039;&#039;&#039;&#039;CMSIS&#039;&#039;&#039;&#039;&#039; Ordner im Projekt Verzeichnis werden aus den Unterorder &#039;&#039;&#039;&#039;&#039;Include&#039;&#039;&#039;&#039;&#039; folgende Dateien dem Projekt hinzugefügt:&lt;br /&gt;
**arm_common_tables.h&lt;br /&gt;
**arm_const_structs.h&lt;br /&gt;
**arm_math.h&lt;br /&gt;
**core_cm4.h&lt;br /&gt;
**core_cm4_simd.h&lt;br /&gt;
**core_cmFunc.h&lt;br /&gt;
**core_cmInstr.h&lt;br /&gt;
*Alle Dateien aus den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projektes&lt;br /&gt;
*Die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; aus dem &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner&lt;br /&gt;
&lt;br /&gt;
So sollte die Struktur dann aussehen:&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_7.png|Anwenungs-Grundgerüst]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Da einige Dateien der Libraries später bearbeitet werden müssen und Schreibgeschützt sind, weise ich hier schonmal darauf hin, das der Schreibschutz in der IDE über &#039;&#039;&#039;&#039;&#039;Rechts Klick auf die Datei -&amp;gt; Properties -&amp;gt; Häkchen bei &amp;quot;File is read only&amp;quot; entfernen&#039;&#039;&#039;&#039;&#039; entfert werden kann.&lt;br /&gt;
&lt;br /&gt;
Damit die IDE die Header-Dateien der CMSIS Library auch finden kann, weil diese ja nicht im standard Include Ordner &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; liegen, muss unter &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Build Options -&amp;gt; Search Directories&#039;&#039;&#039;&#039;&#039; der Pfad &#039;&#039;&#039;&#039;&#039;CMSIS\Include&#039;&#039;&#039;&#039;&#039; hinzugefügt werden.&lt;br /&gt;
&lt;br /&gt;
Compiliert man jetzt das Projekt mit &#039;&#039;&#039;&#039;&#039;F7&#039;&#039;&#039;&#039;&#039; gibt es ein paar Fehler Meldungen, weil keine Controller-Reihe ausgewählt wurde. Ebenfalls unter &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Build Options -&amp;gt; Compiler Settings -&amp;gt; #defines&#039;&#039;&#039;&#039;&#039; wird der Define &#039;&#039;&#039;&#039;&#039;STM32F40_41xxx&#039;&#039;&#039;&#039;&#039; hinzugefügt.&lt;br /&gt;
&lt;br /&gt;
Beim erneuten Compilieren sollten sich nun keine neuen Fehler ergeben.&lt;br /&gt;
&lt;br /&gt;
===Das erste Programm===&lt;br /&gt;
Nachdem ein grundsätzliches &amp;quot;Gerüst&amp;quot; fertig ist, kann man den ersten Code schreiben.&lt;br /&gt;
main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC-&amp;gt;AHB1ENR |= RCC_AHB1ENR_GPIODEN;    //Takt für GPIO aktivieren&lt;br /&gt;
    GPIOD-&amp;gt;MODER |= GPIO_MODER_MODER15_0;   //GPIOD Pin15 als Ausgang&lt;br /&gt;
    GPIOD-&amp;gt;BSRRL |= GPIO_BSRR_BS_15;        //GPIOD Pin15 auf High ziehen&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039; wird dann der Debugger gestartet. Hat der Debugger das Projekt erfolgreich übertragen kann die Ausführung mit &#039;&#039;&#039;&#039;&#039;F5&#039;&#039;&#039;&#039;&#039; begonnen werden.&lt;br /&gt;
&lt;br /&gt;
==Libraries einbinden/verwenden==&lt;br /&gt;
===Einbinden der Standard-Peripheral-Library===&lt;br /&gt;
Um nicht immer die einzelnen Register, wie im ersten &amp;quot;bare-metal&amp;quot; Beispiel, aus dem Reference-Manual zu suchen und zu beschreiben, gibt es von ST die Standard Peripheral Library, die diese Aufgaben übernimmt und mit der sich die &amp;quot;normale/grundlegende&amp;quot; (Alles außer USB und Ethernet) Peripherie recht einfach steuern lässt. Um die Library zu verwenden erzeugt man wie oben beschrieben ein neues Grundgerüst und kopiert als erstes den Ordner &#039;&#039;&#039;&#039;&#039;Libraries\STM32F4xx_StdPeriph_Driver&#039;&#039;&#039;&#039;&#039; aus dem Standard-Peripheral-Library Download in das Projekt-Verzeichnis. Außerdem muss man die Datei &#039;&#039;&#039;&#039;&#039;Project\STM32F4xx_StdPeriph_Templates\stm32f4xx_conf.h&#039;&#039;&#039;&#039;&#039; ebenfalls aus dem Standard-Peripheral-Library Download in den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projektes kopieren. In der IDE fügt man den Include-Path &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\inc&#039;&#039;&#039;&#039;&#039; hinzufügen, wie bei der CMSIS-Library (s.o.).&lt;br /&gt;
Außerdem muss noch &#039;&#039;&#039;&#039;&#039;USE_STDPERIPH_DRIVER&#039;&#039;&#039;&#039;&#039; als Define in der IDE hinzugefügt werden (s.o.).&lt;br /&gt;
Danach fügt man die Source- und Include-Dateien aus dem Ordner &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\inc&#039;&#039;&#039;&#039;&#039; und &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\src&#039;&#039;&#039;&#039;&#039; dem Project mit &#039;&#039;&#039;&#039;&#039;&amp;lt;Project Name&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Add files&#039;&#039;&#039;&#039;&#039; hinzu, allerdings nur die, für welche auch der Controller die entsprechende Peripherie besitzt. Beim STM32F4-Discovery Board / STM32F407VG Controller dürfen also nicht folgende Dateien nicht mit hinzugefügt werden, weil diese Peripherie nur bei anderen Controller vorhanden ist:&lt;br /&gt;
&lt;br /&gt;
*stm32f4xx_dma2d.c/.h&lt;br /&gt;
*stm32f4xx_fmc.c/.h&lt;br /&gt;
*stm32f4xx_ltdc.c/.h&lt;br /&gt;
*stm32f4xx_sai.c/.h&lt;br /&gt;
&lt;br /&gt;
Daraus resultiert folgende Struktur:&lt;br /&gt;
&lt;br /&gt;
[[Datei:stdperiphlib_2.png|Header-Struktur]] [[Datei:stdperiphlib_1.png|Source-Struktur]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Anschließen kann die Standard-Peripheral-Library benutz werden.&lt;br /&gt;
main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);&lt;br /&gt;
&lt;br /&gt;
    GPIO_InitTypeDef GPIOD_InitStructure;&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Mode = GPIO_Mode_OUT;     //Als Ausgang&lt;br /&gt;
    GPIOD_InitStructure.GPIO_OType = GPIO_OType_PP;    //Push-Pull Betrieb&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Pin = GPIO_Pin_15;        //Pin 15 (STM32F4-Discovery: Blaue LED)&lt;br /&gt;
    GPIOD_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;  //Kein Pull-Up oder Pull-Down Widerstand aktiviert&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Speed = GPIO_Speed_25MHz; //25MHz Update-Rate&lt;br /&gt;
    GPIO_Init(GPIOD, &amp;amp;GPIOD_InitStructure);&lt;br /&gt;
&lt;br /&gt;
    GPIO_SetBits(GPIOD, GPIO_Pin_15);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Einbinden der DSP-Library===&lt;br /&gt;
STM32F3 / STM32F4 Microcontroller haben neben der FPU noch einen Digital-Signal-Processor (DSP). Die DSP dient hauptsächlich dazu, viele Daten schnell zu verarbeiten (z.B. Video- oder Audiosignal). Der CMSIS-Download beinhaltet dazu neben der eigentlichen CMSIS-Library auch noch eine DSP-Library. Diese Library stellt sowohl einfache, mathematische Funktionen wie addieren, multiplizieren usw. als auch komplexe Funktionen, wie z.B  einen IIR-Filter, zur Verfügung. Die DSP-Library ist weiter aufgeteilt in kleinere Module, wie z.B. BasicMathFunctions, FilteringFunctions usw. (siehe &#039;&#039;&#039;&#039;&#039;CMSIS\DSP-Library\Source&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
Um die DSP-Library zu verwenden müssen nur die Source-Files des benötigten Moduls einbinden.&lt;br /&gt;
(&#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Add files...&#039;&#039;&#039;&#039;&#039;). Außerdem muss in der &#039;&#039;&#039;&#039;&#039;main.c&#039;&#039;&#039;&#039;&#039; der Include &#039;&#039;&#039;&#039;&#039;arm_math.h&#039;&#039;&#039;&#039;&#039; eingebunden werden. Aus irgendeinem Grund gibt es dann jedoch die Warnung: &amp;quot;Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)&amp;quot;. Ich hab noch nicht rausgefunden, wieso diese Warnung auftaucht. Die Warnung verschwindet, wenn man in der &#039;&#039;&#039;&#039;&#039;Build options...&#039;&#039;&#039;&#039;&#039; das Define &#039;&#039;&#039;&#039;&#039;__FPU_PRESENT&#039;&#039;&#039;&#039;&#039; hinzufügt (Ich weiß selber das das keine schöne Lösung ist, eine andere hab ich jedoch noch nicht gefunden). Jetzt kann die DSP-Library verwedet werden. Das Beispiel multipliziert zwei Buffer miteinander. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
#include &amp;quot;arm_math.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    float32_t x[1024];&lt;br /&gt;
    float32_t y[1024];&lt;br /&gt;
    float32_t z[1024];&lt;br /&gt;
&lt;br /&gt;
    for(uint16_t i = 0; i &amp;lt; 1024; i++)&lt;br /&gt;
    {&lt;br /&gt;
        x[i] = i;&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for(uint16_t i = 0; i &amp;lt; 1024; i++)&lt;br /&gt;
    {&lt;br /&gt;
        y[i] = PI;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    arm_mult_f32(x, y, z, 1024);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Startup-Code, Linker-Script, Takt, FPU, Optimierung usw.==&lt;br /&gt;
===Startup-Code===&lt;br /&gt;
Em::Blocks fügt standardmäßig einen Startup-Code mit in das Projekt ein. Die wichtigsten Dinge die darin erledigt werden sind folgende:&lt;br /&gt;
&lt;br /&gt;
*Stack und Heap wird angelgt&lt;br /&gt;
*Die Vector-Table wird angelegt&lt;br /&gt;
*Ein Default Reset-Handler wird implementiert, dieser erledigt folgende aufgaben:&lt;br /&gt;
**Kopieren der definierten Daten aus dem Flash in den SRAM&lt;br /&gt;
**&#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; wird aufgerfen, wenn &#039;&#039;&#039;&#039;&#039;__NO_SYSTEM_INIT&#039;&#039;&#039;&#039;&#039; nicht definiert ist&lt;br /&gt;
**Sprung in die &#039;&#039;&#039;&#039;&#039;main()&#039;&#039;&#039;&#039;&#039; Funktion&lt;br /&gt;
*Allen anderen Interrupt-Handler wird eine Default-Funktion &#039;&#039;&#039;&#039;&#039;def_irq_handler&#039;&#039;&#039;&#039;&#039; mit einer &#039;&#039;&#039;&#039;&#039;while(1)&#039;&#039;&#039;&#039;&#039;-Schleife zugewiesen, falls kein anderer Interrupt-Handler existiert.&lt;br /&gt;
&lt;br /&gt;
Normalerweise muss am Startup-Code nichts verändert werden.&lt;br /&gt;
&lt;br /&gt;
===Linker-Script===&lt;br /&gt;
Em::Blocks stellt zwei fertige Linker-Scripts bereit, eins für die Ausführung des Programmes aus dem Flash (&#039;&#039;&#039;&#039;&#039;*_flash.ld&#039;&#039;&#039;&#039;&#039;), das andere für die Ausführung aus dem SRAM (&#039;&#039;&#039;&#039;&#039;*_sram.ld&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Normalerweise muss auch hier nichts geändert werden, es sei den Daten sollen in bestimmten Adressbereichen abgelegt werden (z.B. im Core-Coupled RAM), was ich später noch zum Tutorial hinzufüge.&lt;br /&gt;
&lt;br /&gt;
===Der Takt===&lt;br /&gt;
Jeder Controller oder Prozessor braucht einen Takt, indem er die einzelnen Maschinen-Befehle abarbeiten kann.&lt;br /&gt;
Bei den STM32 Mikrocontrollern kann dieser Takt aus verschiedenen Quellen kommen:&lt;br /&gt;
&lt;br /&gt;
1. High Speed Internal Oszillator (HSI)&lt;br /&gt;
&lt;br /&gt;
2. High Speed External Oszillator (HSE)&lt;br /&gt;
&lt;br /&gt;
3. Low Speed Internal Oszillator (LSI)&lt;br /&gt;
&lt;br /&gt;
4. Low Speed External Oszillator (LSE)&lt;br /&gt;
&lt;br /&gt;
5. Phase-Locked Loop (PLL) (generiert den Takt aus den ersten vier Taktquellen durch Teiler und Faktoren)&lt;br /&gt;
&lt;br /&gt;
Nach einem Reset wird der Controller aus der HSI Taktquelle versorgt (16MHz beim STM32F407VG). Um die voll Performance des Controllers zu erreichen muss die PLL verwendet werden, welche den Takt durch geschickte Teiler und Faktoren vervielfältigt, sodass am Ende der Controller mit der maximalen Taktfrequenz läuft. Die notwendige Initialisierung der PLL findet in der Funktion &#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; statt. Die PLL erzeugt zunächst einen Basistakt:&lt;br /&gt;
&lt;br /&gt;
PLL_VCO = (F_HSE / PLL_M) * PLL_N&lt;br /&gt;
&lt;br /&gt;
Aus diesem Takt wird dann der Takt für den Controller-Kern abgeleitet:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = PLL_VCO / PLL_P&lt;br /&gt;
&lt;br /&gt;
Und der Takt für SDIO / USB / RNG (48MHz):&lt;br /&gt;
&lt;br /&gt;
48MHz = PLL_VCO / PLL_Q&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Durch weiter Teiler werden, die Takte für die einzelnen Busse erzeugt, da diese nicht alle beliebig schnell betrieben werden dürfen.&lt;br /&gt;
&lt;br /&gt;
Genaue Angaben findet man zu dem jeweiligen Clock-System des Controllers im Reference Manual.&lt;br /&gt;
&lt;br /&gt;
Ein Blick in den &amp;quot;Kommentar-Header&amp;quot; verrät, dass von einem externen (HSE) Oszillator von 25MHz ausgegangen wird, der die PLL versorgen soll.&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((25MHz / PLL_M(25)) * PLL_N(336)) / PLL_P(2) = 168MHz&lt;br /&gt;
&lt;br /&gt;
Allerdings stimmt diese Rechnung natürlich nur, wenn wirklich ein 25MHz Quarz am Controller angeschlossen ist. Auf dem STM32F4-Discovery Board befindet sich aber nur ein 8MHz Quarz. Demnach gilt:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((8MHz / PLL_M(25)) * PLL_N(336)) / PLL_P(2) = 53.76MHz&lt;br /&gt;
&lt;br /&gt;
Der Controller läuft also nur mit 53.76MHz, wenn wie ober beschrieben ein Projekt erstellt wird. Allerdings kann dieses Problem durch ändern von den betroffen Defines behoben werden:&lt;br /&gt;
 &lt;br /&gt;
*Dazu geht man in die &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; Datei und passt zur Vollständigkeit erstmal die zum Controller passende Tabelle im &amp;quot;Kommentar-Header&amp;quot; an (Z.57f):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      HSE Frequency(Hz)                      | 8000000&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      PLL_M                                  | 8&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Danach passt man den PPL_M Define (Z.254) an:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/************************* PLL Parameters *************************************/&lt;br /&gt;
/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */&lt;br /&gt;
#define PLL_M      8&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Außerdem muss man den HSE_VALUE Define in der &#039;&#039;&#039;&#039;&#039;inc/stm32f4xx.h&#039;&#039;&#039;&#039;&#039; angepasst werden (Z.122):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#if !defined  (HSE_VALUE)&lt;br /&gt;
  #define HSE_VALUE    ((uint32_t)8000000) /*!&amp;lt; Value of the External oscillator in Hz */&lt;br /&gt;
&lt;br /&gt;
#endif /* HSE_VALUE */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine neue Berechnung zeigt:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((8MHz / PLL_M(8)) * PLL_N(336)) / PLL_P(2) = 168MHz&lt;br /&gt;
&lt;br /&gt;
Jetzt läuft der Controller mit maximaler Geschwindigkeit.&lt;br /&gt;
&lt;br /&gt;
Die Theorie wird durch folgendes Programm verifiziert. Der geviertelte System-Takt SYSCLK wir am Pin PC9 ausgegeben. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);&lt;br /&gt;
&lt;br /&gt;
    GPIO_InitTypeDef GPIOC_InitStructure;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Mode = GPIO_Mode_AF;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_OType = GPIO_OType_PP;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Pin = GPIO_Pin_9;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;&lt;br /&gt;
    GPIO_Init(GPIOC, &amp;amp;GPIOC_InitStructure);&lt;br /&gt;
&lt;br /&gt;
    RCC_MCO2Config(RCC_MCO2Source_SYSCLK, RCC_MCO2Div_4);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Die FPU===&lt;br /&gt;
====Allgemeines====&lt;br /&gt;
Damit die FPU richtig verwendet wird, müssen normalerweise zwei Bedingungen erfüllt sein:&lt;br /&gt;
&lt;br /&gt;
1. Der Controller muss in der Initialisierung-Funktion &#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; in &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; die FPU Hardware-seitig aktivieren&lt;br /&gt;
&lt;br /&gt;
2. Damit die FPU auch was zu tuen bekommt, müssen vom Compiler FPU-Instructions erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
Die Em::Blocks IDE verwendet standardmäßig die FPU, wenn eine Vorhanden ist. Hier wird die FPU Hardware-seitig aktiviert (&#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; Z.341):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* FPU settings ------------------------------------------------------------*/&lt;br /&gt;
  #if (__FPU_PRESENT == 1) &amp;amp;&amp;amp; (__FPU_USED == 1)&lt;br /&gt;
    SCB-&amp;gt;CPACR |= ((3UL &amp;lt;&amp;lt; 10*2)|(3UL &amp;lt;&amp;lt; 11*2));  /* set CP10 and CP11 Full Access */&lt;br /&gt;
  #endif&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
__FPU_PRESENT wird in der &#039;&#039;&#039;&#039;&#039;stm32f4xx.h&#039;&#039;&#039;&#039;&#039; definiert.&lt;br /&gt;
__FPU_USED wird von der IDE übernommen (siehe Build-Log): &#039;&#039;&#039;&#039;&#039;-D__FPU_USED&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Außerdem wird der Compiler von der IDE standardmäßig mit dem Argument &#039;&#039;&#039;&#039;&#039;-mfloat-abi=hard&#039;&#039;&#039;&#039;&#039; aufgerufen, wodurch FPU-Instructions erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
====FPU abschalten====&lt;br /&gt;
Um die FPU ab zu schalten (Mir würde jetzt nur Strom sparen als Grund einfallen) geht man wie folgt vor:&lt;br /&gt;
&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick Build options -&amp;gt; Device -&amp;gt; Policy&#039;&#039;&#039;&#039;&#039; wählt man &#039;&#039;&#039;&#039;&#039;Use target settings&#039;&#039;&#039;&#039;&#039; und über nimmt die Einstellungen, die vorher dort eingetragen waren, allerdings lässt man das Feld &#039;&#039;&#039;&#039;&#039;FP-hardware&#039;&#039;&#039;&#039;&#039; frei.&lt;br /&gt;
&lt;br /&gt;
[[Datei:fpu_1.png|FPU Abschalten Schritt 1]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;Compiler Settings -&amp;gt; Policy&#039;&#039;&#039;&#039;&#039; wählt man dann &#039;&#039;&#039;&#039;&#039;Use target options only&#039;&#039;&#039;&#039;&#039;. Dann kann man unter &#039;&#039;&#039;&#039;&#039;Categories&#039;&#039;&#039;&#039;&#039; die Option &#039;&#039;&#039;&#039;&#039;ARM FPU architecture&#039;&#039;&#039;&#039;&#039; auswählen. Dort stehen dann drei Möglichkeiten für die FPU zur Verfügung:&lt;br /&gt;
&lt;br /&gt;
1. Software-FPU-Library für Gleitkomma-Berechnung verwenden - Keine FPU-Instructions werden generiert (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=soft&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
2. Eine Mischung aus Software- und Hardware-FPU wird verwendet (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=softfp&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
3. Hardware-FPU wird für Gleitkomma-Berechnungen verwendet (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=hard&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
[[Datei:fpu_2.png|FPU Abschalten Schritt 2]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Um die FPU ab zu schalten wählt man natürlich die erste Möglichkeit.&lt;br /&gt;
Bei der 2. und 3. Möglichkeit fügt die IDE auch den Define &#039;&#039;&#039;&#039;&#039;__FPU_USED&#039;&#039;&#039;&#039;&#039; hinzu. Bei Der ersten Möglichkeit nicht. Der Code muss also nicht verändert / auskommentiert werden.&lt;br /&gt;
&lt;br /&gt;
Um die FPU wieder zu aktivieren müssen alle Schritte wieder rückgängig gemacht werden.&lt;br /&gt;
&lt;br /&gt;
Am besten ist es einfach mal alle Möglichkeiten im Einzelschritt durch zu probieren. Dann stellt man schnell fest, ob die FPU aktiviert wir oder nicht. Ein Blick in den erweiterten &#039;&#039;&#039;&#039;&#039;Build-Log&#039;&#039;&#039;&#039;&#039; gibt auch schnell Aufschluss darüber, wie der Compiler aufgerufen wird (siehe Kapitel [http://www.mikrocontroller.net/articles/STM32_-_Einstieg_mit_Em::Blocks#Compilieren Compilieren]).&lt;br /&gt;
&lt;br /&gt;
====Test Programm für die FPU====&lt;br /&gt;
Hier ein kleines Testprogramm, dass misst wie viele Taktzyklen für eine Gleitkomma-Multiplikation gebraucht werden. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define CORE_SysTickEn()    (*((u32*)0xE0001000)) = 0x40000001&lt;br /&gt;
#define CORE_SysTickDis()   (*((u32*)0xE0001000)) = 0x40000000&lt;br /&gt;
#define CORE_GetSysTick()   (*((u32*)0xE0001004))&lt;br /&gt;
&lt;br /&gt;
uint32_t t1, t2, dt;&lt;br /&gt;
float x, y, z;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    x = 53.64f;&lt;br /&gt;
    y = 0.27f;&lt;br /&gt;
&lt;br /&gt;
    CORE_SysTickEn();&lt;br /&gt;
    t1 = CORE_GetSysTick();&lt;br /&gt;
&lt;br /&gt;
    z = x * y;&lt;br /&gt;
&lt;br /&gt;
    t2 = CORE_GetSysTick();&lt;br /&gt;
    CORE_SysTickDis();&lt;br /&gt;
&lt;br /&gt;
    dt = (t2 - t1) - 9; //9 Takt-Zyklen werden für die Messung gebraucht &lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Compiler-Optimierung===&lt;br /&gt;
Standardmäßig verwendet Em::Blocks keine Optimierung. Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; Categories: Optimization&#039;&#039;&#039;&#039;&#039; kann zwischen verschieden Optimierungen ausgewählt werden.&lt;br /&gt;
&lt;br /&gt;
==Booten aus dem SRAM==&lt;br /&gt;
STM32 Controller haben die Möglichkeit Code aus dem Flash als auch aus dem SRAM auszuführen. Um eine Anwenung per Debugger in des SRAM zu laden sind nur wenige Schritte erforderlich:&lt;br /&gt;
&lt;br /&gt;
*Um das Linkerscript für den SRAM zu verwenden geht man zu: &#039;&#039;&#039;&#039;&#039;Build options... -&amp;gt; Device&#039;&#039;&#039;&#039;&#039; dort wählt man unter &#039;&#039;&#039;&#039;&#039;Policy&#039;&#039;&#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;Use target settings&#039;&#039;&#039;&#039;&#039; aus und übernimmt die vorherigen Einstellungen, nur unter &#039;&#039;&#039;&#039;&#039;Linker script*&#039;&#039;&#039;&#039;&#039; gibt man &#039;&#039;&#039;&#039;&#039;.\stm32f407vg_sram.ld&#039;&#039;&#039;&#039;&#039; an&lt;br /&gt;
&lt;br /&gt;
*Dann muss man noch unter &#039;&#039;&#039;&#039;&#039;Debug -&amp;gt; Interfaces -&amp;gt; Settings&#039;&#039;&#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;Vector table start&#039;&#039;&#039;&#039;&#039; auf 0x20000000 ändern und &#039;&#039;&#039;&#039;&#039;Execute from RAM&#039;&#039;&#039;&#039;&#039; auswählen.&lt;br /&gt;
&lt;br /&gt;
Anschließend kann man die Anwendung ganz normal debuggen. Nach einem Reset muss die Anwenung erneut mit dem Debugger gestartet werden.&lt;br /&gt;
&lt;br /&gt;
=Fortsetzung folgt..=&lt;br /&gt;
Kritik, Wünsche usw. sind gerne erwünscht, am besten hier in den Thread posten: [http://www.mikrocontroller.net/topic/323750 Neues STM32 Tutorial]&lt;br /&gt;
&lt;br /&gt;
[[Category:ARM]]&lt;br /&gt;
[[Category:STM32]]&lt;/div&gt;</summary>
		<author><name>Avrprogger</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=STM32_-_Einstieg_mit_Em::Blocks&amp;diff=81538</id>
		<title>STM32 - Einstieg mit Em::Blocks</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=STM32_-_Einstieg_mit_Em::Blocks&amp;diff=81538"/>
		<updated>2014-02-11T16:36:13Z</updated>

		<summary type="html">&lt;p&gt;Avrprogger: cvb&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In diesem Tutorial werde ich versuchen, möglichst einfach, die ersten Schritte zur Entwicklung von STM32 Anwenungen mit der Em::Blocks IDE zu erklären. Hier soll nicht so stark auf die einzelnen Peripherie-Module der Controller eingegangen werden, sondern mehr auf die IDE und die verschieden Libraries, wie die CMSIS Library, die DSP-Library, die Standard-Peripheral-Library, die USB-Library und vllt. über Ethernet. Ich denke ein Kapitel zu FreeRTOS wird es auch geben. Auserdem steht im Vordergrund Sachen wie z.B. booten aus dem SRAM, In-Application-Programming, FPU, Core-Coupled-RAM usw. Mal sehn wie weit ich komme ;)&lt;br /&gt;
&lt;br /&gt;
==Die Entwicklungsumgebung==&lt;br /&gt;
===Hardware===&lt;br /&gt;
Zum testen der Anwendungen, benutze ich das STM32F4-Discovery Board, welches einen Debugger, Peripherie und natürlich einen STM32 Controller (STM32F407VGT6) enthält. Deshalb sind alle Beispiele hier für den STM32F407VG Controller ausgelegt, können aber meisten 1:1 auf andere Controller portiert werden. Ich werde auch möglichsts keine STM32F4-Discovery Board spezifischen Libraries verwenden, damit der Portierungs-Vorgang möglichsts einfach bleibt.&lt;br /&gt;
&lt;br /&gt;
===Software===&lt;br /&gt;
In diesem Tutorial verwende ich [http://www.emblocks.org/ Em::Blocks] als IDE. Em::Blocks ist eine kostenlose, uneingeschränkte IDE, die alle STM32 Mikrcontroller unterstützt und sehr einfach zu bedienen ist.&lt;br /&gt;
nach dem Download kann die IDE per Dialog, sehr einfach, installiert werden. Als Compiler beinhaltet Em::Blocks den &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
Die IDE unterstützt zurzeit den ST-Link, den J-Link und es gibt eine Generic-Vorlage, durch welche andere Debugger konfiguriert werden können.&lt;br /&gt;
&lt;br /&gt;
Außerdem muss noch der passende Treiber für den Debugger installiert werden. Verwendet man ein Discovery-Board muss der [http://www.st.com/web/catalog/tools/FM146/CL1984/SC724/SS1677/PF251168 ST-Link/V2]-Treiber heruntergeladen und installiert werden. (Die Installation muss evtl. als Administrator ausgeführt werden, da sonst die Installation unvollständig wird.) Nach der Installation des Treibers kann man den Debugger über die entsprechende USB Schnittstelle an den PC anschließen und es sollte die Meldung von Windows kommen, dass der richtige Treiber gefunden wurde.&lt;br /&gt;
&lt;br /&gt;
===Libraries===&lt;br /&gt;
Zum programmieren benötigt man noch die [http://www.arm.com/products/processors/cortex-m/cortex-microcontroller-software-interface-standard.php CMSIS] und die Standard-Peripheral-Library (z.B. für die F4 Controller [http://www.st.com/stonline/stappl/productcatalog/app?page=partNumberSearchPage&amp;amp;levelid=SS1577&amp;amp;parentid=1743&amp;amp;resourcetype=SW Standard-Peripheral-Library-F4]), die man am besten in einen Ordner (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\STM32&#039;&#039;&#039;&#039;&#039;) entpackt&lt;br /&gt;
&lt;br /&gt;
==Basis-Wissen zur IDE==&lt;br /&gt;
Einige Grundfunktionalitäten der IDE:&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von Dateien zum Projekt===&lt;br /&gt;
Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf &amp;lt;ProjektName&amp;gt; -&amp;gt; Add files...&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Enfernen von Dateien aus dem Projekt===&lt;br /&gt;
Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf die Datei / mehrere Dateien auswählen -&amp;gt; Remove file from project&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
Die Dateien werden lediglich aus dem Projekt entfernt und nicht von der Festplatte gelöscht.&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von Include-Pfaden===&lt;br /&gt;
Sofern die Include-Datei(en) nicht im standard Include-Ordner &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; des Projektes liegen, muss man den Pfad zum Projekt hinzufügen, damit der Compiler die Include-Dateien später auch finden kann. Man geht wie folgt vor: Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf &amp;lt;ProjektName&amp;gt; -&amp;gt; Build options... -&amp;gt; Search Directories -&amp;gt; Add&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von globalen Defines zum Build===&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; #defines&#039;&#039;&#039;&#039;&#039; können globale Defines hinzugefügt werden.&lt;br /&gt;
&lt;br /&gt;
===Compilieren===&lt;br /&gt;
Entweder über das &#039;&#039;&#039;&#039;&#039;Build&#039;&#039;&#039;&#039;&#039; Menü oder über &#039;&#039;&#039;&#039;&#039;F7&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Um eine genau Ausgabe des Compiler-Aufrufes mit allen Argumenten zu bekommen, geht man im &#039;&#039;&#039;&#039;&#039;Settings&#039;&#039;&#039;&#039;&#039; Menü auf &#039;&#039;&#039;&#039;&#039;Tools...&#039;&#039;&#039;&#039;&#039; und dann auf &#039;&#039;&#039;&#039;&#039;Toolchain executables&#039;&#039;&#039;&#039;&#039;. Ganz unten, unter &#039;&#039;&#039;&#039;&#039;Logging&#039;&#039;&#039;&#039;&#039; kann man dann &#039;&#039;&#039;&#039;&#039;Full command line&#039;&#039;&#039;&#039;&#039; auswählen.&lt;br /&gt;
&lt;br /&gt;
====Compiler Optionen====&lt;br /&gt;
=====Optimierung=====&lt;br /&gt;
=====Verschiedene C-Standards=====&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; Categories: Language standard&#039;&#039;&#039;&#039;&#039; kann man zwischen verschieden C-Standard auswählen, wie z.B, C99.&lt;br /&gt;
(Mit C99 können auch die Lauf-Variable in der for-Schleife deklariert werden: for(int i;..))&lt;br /&gt;
&lt;br /&gt;
===Debuggen===&lt;br /&gt;
*Als erstes den Debugger starten über das &#039;&#039;&#039;&#039;&#039;Debug&#039;&#039;&#039;&#039;&#039; Menü und &#039;&#039;&#039;&#039;&#039;Start/stop Debug Session&#039;&#039;&#039;&#039;&#039; oder über &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
*Danach läuft die Anwendung auf dem Controller und warten im &#039;&#039;&#039;&#039;&#039;Reset_Handler&#039;&#039;&#039;&#039;&#039; auf Einzelschritt- bzw. Run- Befehle (&#039;&#039;&#039;&#039;&#039;F5, F10, F11&#039;&#039;&#039;&#039;&#039; usw..(siehe &#039;&#039;&#039;&#039;&#039;Debug-Menü&#039;&#039;&#039;&#039;&#039; für alle Möglichkeiten))&lt;br /&gt;
&lt;br /&gt;
*Mit &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039; wird die Debug-Session auch wieder beendet&lt;br /&gt;
&lt;br /&gt;
*Unter &#039;&#039;&#039;&#039;&#039;Debug -&amp;gt; Interfaces -&amp;gt; Target settings&#039;&#039;&#039;&#039;&#039; können Eigenschaften, wie z.B &#039;&#039;&#039;&#039;&#039;Run to main()&#039;&#039;&#039;&#039;&#039; aktiviert werden.&lt;br /&gt;
&lt;br /&gt;
===Projekt als Template abspeichern===&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;File -&amp;gt; Save project as template...&#039;&#039;&#039;&#039;&#039;. Das Template erscheint dann im Projekt-Dialog unter &#039;&#039;&#039;&#039;&#039;User templates&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Das erste Projekt erstellen==&lt;br /&gt;
Hier erkläre ich, wie man am Besten (aus meiner Sicht), ein neues Projekt von Grund auf erstellt, sodass man hinterher, den Controller-Kern über die CMSIS-Library und die Peripherie über die Register steuern kann.&lt;br /&gt;
&lt;br /&gt;
===1. Projekt mit der IDE erstellen===&lt;br /&gt;
Nach der Installation der oben beschriebenen Komponenten erstellt man am besten ein Verzeichnis (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\EmBlocks&#039;&#039;&#039;&#039;&#039;), indem später alle Projekte gespeichert werden. Für Libraries kann man auch noch ein Verzeichnis (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\STM32&#039;&#039;&#039;&#039;&#039;) erstellen, wo alle Libraries gespeichert werden, die man für die Projekt brauchen.&lt;br /&gt;
&lt;br /&gt;
Als nächstes starten man EmBlocks. Bei dem ersten Start öffnet sich ein Fenster, wo verschiedene Compiler angezeigt werden, die Em::Blocks findet. Dort wählt man den &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039; aus und klickt &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039;. Nun sollte sich das Hauptfenster von Em::Blocks öffnen. Über &#039;&#039;&#039;&#039;&#039;Create a new Project&#039;&#039;&#039;&#039;&#039; oder &#039;&#039;&#039;&#039;&#039;File -&amp;gt; New -&amp;gt; Project&#039;&#039;&#039;&#039;&#039; ruft man den Projekt-Dialog auf und kann ein neues Projekt erzeugen.&lt;br /&gt;
&lt;br /&gt;
Auf der Ersten Seite wählen man den &#039;&#039;&#039;&#039;&#039;STmicro-ARM&#039;&#039;&#039;&#039;&#039; Projekt-Typ aus.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_1.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auf der nächsten Seite wird man darauf hingewiesen, dass das der entsprechende Projekt-Typ-Dialog ausgeführt wird. Hier kann man ein Häkchen bei &#039;&#039;&#039;&#039;&#039;Skip this page next time&#039;&#039;&#039;&#039;&#039; setzen und auf &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; klicken.&lt;br /&gt;
&lt;br /&gt;
Im nächsten Schritt wählen man das zuvor erstellt Verzeichnis unter &#039;&#039;&#039;&#039;&#039;Folder to create Project in&#039;&#039;&#039;&#039;&#039; aus, indem später alle Projekt gespeichert werden. Außerdem geben wir dem Projekt einen Namen (z.B. &#039;&#039;&#039;&#039;&#039;FirstProject&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_2.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danach muss man einen Compiler auswählen und bestimmen, welche Projekt-Konfigurationen erszeugt werden sollen. Unter &#039;&#039;&#039;&#039;&#039;Compiler&#039;&#039;&#039;&#039;&#039; wählt man &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039; und man kann das Häkchen bei &#039;&#039;&#039;&#039;&#039;Create &amp;quot;Release&amp;quot; configuration&#039;&#039;&#039;&#039;&#039; entfernen, da diese unnötig ist, die Debug-Konfiguration sollte eig. immer ausreichen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_3.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auf den folgenden Seite wird der Controller ausgewählt. Verwendet man ein STM32F4-Discovery Board müssen folgende Dinge gewählt werden: &#039;&#039;&#039;&#039;&#039;Cortex_M4 (F3xx - F4xx) -&amp;gt; STM32F4xx (Cortex M4 with FPU) -&amp;gt; STM32F407VG&#039;&#039;&#039;&#039;&#039;. Leider sind die Auswahl Möglichkeiten nicht ganz richtig, da auch die F3 Controller einen Cortex M4 Kern und eine FPU haben (Ist aber nicht so wichtig, ist nur eine formale Sache). Außerdem entfernt man das Häkchen bei &#039;&#039;&#039;&#039;&#039;Standard Peripherals Library&#039;&#039;&#039;&#039;&#039; (Wie man die Standard-Peripheral-Library einbindet und verwendet erkläre ich später). Man kann auch das Häkchen bei &#039;&#039;&#039;&#039;&#039;Create hex file for Realease target&#039;&#039;&#039;&#039;&#039; entfernen.&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;Stack Size&#039;&#039;&#039;&#039;&#039; und &#039;&#039;&#039;&#039;&#039;Heap Size&#039;&#039;&#039;&#039;&#039; wird die Größe von Stack und Heap festgelegt. Für eine erste Anwendung kann man die Einstellungen so lassen (Stack-Size: 0x0100 =&amp;gt; 256 Byte Stack und Heap-Size: 0x0000 =&amp;gt; kein Heap). Mit &#039;&#039;&#039;&#039;&#039;Finish&#039;&#039;&#039;&#039;&#039; ist der Projekt Dialog abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_4.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danach sollten sich zwei neue Fenster öffnen, um die Debug-Eigenschaften fest zu legen.&lt;br /&gt;
Verwendet man ein Discovery Board/ST-Link müssen die Einstellungen wie auf dem Bild gewählt werden. Über den Button &#039;&#039;&#039;&#039;&#039;Settings&#039;&#039;&#039;&#039;&#039; öffnet sich das zweite Fenster, falls sich dieses nicht schon von alleine öffnen sollte. Nach den Schließen der Fenster über &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; ist der Projekt Dialog beendet und ein neues Projekt steht zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_5_1.png|Debug Eigenschaften 1. Fenster]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_5_2.png|Debug Eigenschaften 2. Fenster]]&lt;br /&gt;
&lt;br /&gt;
===2. CMSIS-Library und Startup-Code hinzufügen===&lt;br /&gt;
Wenn man sich, nachdem man ein neues Projekt in der IDE erstellt hat, die bereits vorhandenen Dateien im Projekt ansieht, stellt man fest, das bereits ein Ordner &#039;&#039;&#039;&#039;&#039;cmsis&#039;&#039;&#039;&#039;&#039; existiert, der einige wichtige Include-Dateien der CMSIS-Library enthält. Allerdings sind das wirklich nur die wichtigsten Include-Dateien der CMSIS-Library und dazu noch, die aus einer älternen Version. Ich ziehe es deshalb vor die &amp;quot;Mini-CMSIS-Libraray&amp;quot; und die &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c/.h&#039;&#039;&#039;&#039;&#039; Dateien des Projektes durch aktuellere Versionen zu ersetzen. So ist später auch die Integration  von anderen Libraries, wie z.B. der CMSIS-DSP-Libarary einfacher.  &lt;br /&gt;
&lt;br /&gt;
Zunächst gehen man in das Projekt-Verzeichnis und löscht:&lt;br /&gt;
*Den Ordner &#039;&#039;&#039;&#039;&#039;cmsis&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Alle Dateien im Include Verzeichnis &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; im &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner&lt;br /&gt;
&lt;br /&gt;
Außerdem entfernt man auch alle gelöschten Dateien in der IDE aus dem Projekt mit &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Rechts Klick -&amp;gt; Remove file from project&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Es sollte folgende Verzeichnis Struktur überbleiben:&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_6.png|Überbleibende Dateien]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Jetzt müssen die gelöschten Dateien durch die aktuelleren ersetzt werden.&lt;br /&gt;
&lt;br /&gt;
*Dazu kopieren man den gesamten Ordner &#039;&#039;&#039;&#039;&#039;CMSIS&#039;&#039;&#039;&#039;&#039; aus dem CMSIS Download in das Projekt Verzeichnis.&lt;br /&gt;
&lt;br /&gt;
*Aus dem Standard-Peripheral-Library Download kopiert man von &#039;&#039;&#039;&#039;&#039;Libraries\CMSIS\Device\ST\STM32F4xx\Include&#039;&#039;&#039;&#039;&#039; alle Dateien in den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projekt Verzeichnisses&lt;br /&gt;
&lt;br /&gt;
*Aus der Standard-Peripheral-Library kopieren man ebenfalls von &#039;&#039;&#039;&#039;&#039;Libraries\CMSIS\Device\ST\STM32F4xx\Source\Templates&#039;&#039;&#039;&#039;&#039; die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; in den &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner des Projekts&lt;br /&gt;
&lt;br /&gt;
Anschließend müssen die neuen Dateien in der IDE dem Projekt hinzugefügt werden. Dazu benutzt man &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Rechts Klick -&amp;gt; Add files&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
*Aus dem &#039;&#039;&#039;&#039;&#039;CMSIS&#039;&#039;&#039;&#039;&#039; Ordner im Projekt Verzeichnis werden aus den Unterorder &#039;&#039;&#039;&#039;&#039;Include&#039;&#039;&#039;&#039;&#039; folgende Dateien dem Projekt hinzugefügt:&lt;br /&gt;
**arm_common_tables.h&lt;br /&gt;
**arm_const_structs.h&lt;br /&gt;
**arm_math.h&lt;br /&gt;
**core_cm4.h&lt;br /&gt;
**core_cm4_simd.h&lt;br /&gt;
**core_cmFunc.h&lt;br /&gt;
**core_cmInstr.h&lt;br /&gt;
*Alle Dateien aus den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projektes&lt;br /&gt;
*Die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; aus dem &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner&lt;br /&gt;
&lt;br /&gt;
So sollte die Struktur dann aussehen:&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_7.png|Anwenungs-Grundgerüst]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Da einige Dateien der Libraries später bearbeitet werden müssen und Schreibgeschützt sind, weise ich hier schonmal darauf hin, das der Schreibschutz in der IDE über &#039;&#039;&#039;&#039;&#039;Rechts Klick auf die Datei -&amp;gt; Properties -&amp;gt; Häkchen bei &amp;quot;File is read only&amp;quot; entfernen&#039;&#039;&#039;&#039;&#039; entfert werden kann.&lt;br /&gt;
&lt;br /&gt;
Damit die IDE die Header-Dateien der CMSIS Library auch finden kann, weil diese ja nicht im standard Include Ordner &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; liegen, muss unter &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Build Options -&amp;gt; Search Directories&#039;&#039;&#039;&#039;&#039; der Pfad &#039;&#039;&#039;&#039;&#039;CMSIS\Include&#039;&#039;&#039;&#039;&#039; hinzugefügt werden.&lt;br /&gt;
&lt;br /&gt;
Compiliert man jetzt das Projekt mit &#039;&#039;&#039;&#039;&#039;F7&#039;&#039;&#039;&#039;&#039; gibt es ein paar Fehler Meldungen, weil keine Controller-Reihe ausgewählt wurde. Ebenfalls unter &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Build Options -&amp;gt; Compiler Settings -&amp;gt; #defines&#039;&#039;&#039;&#039;&#039; wird der Define &#039;&#039;&#039;&#039;&#039;STM32F40_41xxx&#039;&#039;&#039;&#039;&#039; hinzugefügt.&lt;br /&gt;
&lt;br /&gt;
Beim erneuten Compilieren sollten sich nun keine neuen Fehler ergeben.&lt;br /&gt;
&lt;br /&gt;
===Das erste Programm===&lt;br /&gt;
Nachdem ein grundsätzliches &amp;quot;Gerüst&amp;quot; fertig ist, kann man den ersten Code schreiben.&lt;br /&gt;
main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC-&amp;gt;AHB1ENR |= RCC_AHB1ENR_GPIODEN;    //Takt für GPIO aktivieren&lt;br /&gt;
    GPIOD-&amp;gt;MODER |= GPIO_MODER_MODER15_0;   //GPIOD Pin15 als Ausgang&lt;br /&gt;
    GPIOD-&amp;gt;BSRRL |= GPIO_BSRR_BS_15;        //GPIOD Pin15 auf High ziehen&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039; wird dann der Debugger gestartet. Hat der Debugger das Projekt erfolgreich übertragen kann die Ausführung mit &#039;&#039;&#039;&#039;&#039;F5&#039;&#039;&#039;&#039;&#039; begonnen werden.&lt;br /&gt;
&lt;br /&gt;
==Libraries einbinden/verwenden==&lt;br /&gt;
===Einbinden der Standard-Peripheral-Library===&lt;br /&gt;
Um nicht immer die einzelnen Register, wie im ersten &amp;quot;bare-metal&amp;quot; Beispiel, aus dem Reference-Manual zu suchen und zu beschreiben, gibt es von ST die Standard Peripheral Library, die diese Aufgaben übernimmt und mit der sich die &amp;quot;normale/grundlegende&amp;quot; (Alles außer USB und Ethernet) Peripherie recht einfach steuern lässt. Um die Library zu verwenden erzeugt man wie oben beschrieben ein neues Grundgerüst und kopiert als erstes den Ordner &#039;&#039;&#039;&#039;&#039;Libraries\STM32F4xx_StdPeriph_Driver&#039;&#039;&#039;&#039;&#039; aus dem Standard-Peripheral-Library Download in das Projekt-Verzeichnis. Außerdem muss man die Datei &#039;&#039;&#039;&#039;&#039;Project\STM32F4xx_StdPeriph_Templates\stm32f4xx_conf.h&#039;&#039;&#039;&#039;&#039; ebenfalls aus dem Standard-Peripheral-Library Download in den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projektes kopieren. In der IDE fügt man den Include-Path &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\inc&#039;&#039;&#039;&#039;&#039; hinzufügen, wie bei der CMSIS-Library (s.o.).&lt;br /&gt;
Außerdem muss noch &#039;&#039;&#039;&#039;&#039;USE_STDPERIPH_DRIVER&#039;&#039;&#039;&#039;&#039; als Define in der IDE hinzugefügt werden (s.o.).&lt;br /&gt;
Danach fügt man die Source- und Include-Dateien aus dem Ordner &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\inc&#039;&#039;&#039;&#039;&#039; und &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\src&#039;&#039;&#039;&#039;&#039; dem Project mit &#039;&#039;&#039;&#039;&#039;&amp;lt;Project Name&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Add files&#039;&#039;&#039;&#039;&#039; hinzu, allerdings nur die, für welche auch der Controller die entsprechende Peripherie besitzt. Beim STM32F4-Discovery Board / STM32F407VG Controller dürfen also nicht folgende Dateien nicht mit hinzugefügt werden, weil diese Peripherie nur bei anderen Controller vorhanden ist:&lt;br /&gt;
&lt;br /&gt;
*stm32f4xx_dma2d.c/.h&lt;br /&gt;
*stm32f4xx_fmc.c/.h&lt;br /&gt;
*stm32f4xx_ltdc.c/.h&lt;br /&gt;
*stm32f4xx_sai.c/.h&lt;br /&gt;
&lt;br /&gt;
Daraus resultiert folgende Struktur:&lt;br /&gt;
&lt;br /&gt;
[[Datei:stdperiphlib_2.png|Header-Struktur]] [[Datei:stdperiphlib_1.png|Source-Struktur]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Anschließen kann die Standard-Peripheral-Library benutz werden.&lt;br /&gt;
main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);&lt;br /&gt;
&lt;br /&gt;
    GPIO_InitTypeDef GPIOD_InitStructure;&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Mode = GPIO_Mode_OUT;     //Als Ausgang&lt;br /&gt;
    GPIOD_InitStructure.GPIO_OType = GPIO_OType_PP;    //Push-Pull Betrieb&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Pin = GPIO_Pin_15;        //Pin 15 (STM32F4-Discovery: Blaue LED)&lt;br /&gt;
    GPIOD_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;  //Kein Pull-Up oder Pull-Down Widerstand aktiviert&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Speed = GPIO_Speed_25MHz; //25MHz Update-Rate&lt;br /&gt;
    GPIO_Init(GPIOD, &amp;amp;GPIOD_InitStructure);&lt;br /&gt;
&lt;br /&gt;
    GPIO_SetBits(GPIOD, GPIO_Pin_15);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Einbinden der DSP-Library===&lt;br /&gt;
STM32F3 / STM32F4 Microcontroller haben neben der FPU noch einen Digital-Signal-Processor (DSP). Die DSP dient hauptsächlich dazu, viele Daten schnell zu verarbeiten (z.B. Video- oder Audiosignal). Der CMSIS-Download beinhaltet dazu neben der eigentlichen CMSIS-Library auch noch eine DSP-Library. Diese Library stellt sowohl einfache, mathematische Funktionen wie addieren, multiplizieren usw. als auch komplexe Funktionen, wie z.B  einen IIR-Filter, zur Verfügung. Die DSP-Library ist weiter aufgeteilt in kleinere Module, wie z.B. BasicMathFunctions, FilteringFunctions usw. (siehe &#039;&#039;&#039;&#039;&#039;CMSIS\DSP-Library\Source&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
Um die DSP-Library zu verwenden müssen nur die Source-Files des benötigten Moduls einbinden.&lt;br /&gt;
(&#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Add files...&#039;&#039;&#039;&#039;&#039;). Außerdem muss in der &#039;&#039;&#039;&#039;&#039;main.c&#039;&#039;&#039;&#039;&#039; der Include &#039;&#039;&#039;&#039;&#039;arm_math.h&#039;&#039;&#039;&#039;&#039; eingebunden werden. Aus irgendeinem Grund gibt es dann jedoch die Warnung: &amp;quot;Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)&amp;quot;. Ich hab noch nicht rausgefunden, wieso diese Warnung auftaucht. Die Warnung verschwindet, wenn man in der &#039;&#039;&#039;&#039;&#039;Build options...&#039;&#039;&#039;&#039;&#039; das Define &#039;&#039;&#039;&#039;&#039;__FPU_PRESENT&#039;&#039;&#039;&#039;&#039; hinzufügt (Ich weiß selber das das keine schöne Lösung ist, eine andere hab ich jedoch noch nicht gefunden). Jetzt kann die DSP-Library verwedet werden. Das Beispiel multipliziert zwei Buffer miteinander. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
#include &amp;quot;arm_math.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    float32_t x[1024];&lt;br /&gt;
    float32_t y[1024];&lt;br /&gt;
    float32_t z[1024];&lt;br /&gt;
&lt;br /&gt;
    for(uint16_t i = 0; i &amp;lt; 1024; i++)&lt;br /&gt;
    {&lt;br /&gt;
        x[i] = i;&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for(uint16_t i = 0; i &amp;lt; 1024; i++)&lt;br /&gt;
    {&lt;br /&gt;
        y[i] = PI;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    arm_mult_f32(x, y, z, 1024);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Startup-Code, Linker-Script, Takt, FPU, Optimierung usw.==&lt;br /&gt;
===Startup-Code===&lt;br /&gt;
Em::Blocks fügt standardmäßig einen Startup-Code mit in das Projekt ein. Die wichtigsten Dinge die darin erledigt werden sind folgende:&lt;br /&gt;
&lt;br /&gt;
*Stack und Heap wird angelgt&lt;br /&gt;
*Die Vector-Table wird angelegt&lt;br /&gt;
*Ein Default Reset-Handler wird implementiert, dieser erledigt folgende aufgaben:&lt;br /&gt;
**Kopieren der definierten Daten aus dem Flash in den SRAM&lt;br /&gt;
**&#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; wird aufgerfen, wenn &#039;&#039;&#039;&#039;&#039;__NO_SYSTEM_INIT&#039;&#039;&#039;&#039;&#039; nicht definiert ist&lt;br /&gt;
**Sprung in die &#039;&#039;&#039;&#039;&#039;main()&#039;&#039;&#039;&#039;&#039; Funktion&lt;br /&gt;
*Allen anderen Interrupt-Handler wird eine Default-Funktion &#039;&#039;&#039;&#039;&#039;def_irq_handler&#039;&#039;&#039;&#039;&#039; mit einer &#039;&#039;&#039;&#039;&#039;while(1)&#039;&#039;&#039;&#039;&#039;-Schleife zugewiesen, falls kein anderer Interrupt-Handler existiert.&lt;br /&gt;
&lt;br /&gt;
Normalerweise muss am Startup-Code nichts verändert werden.&lt;br /&gt;
&lt;br /&gt;
===Linker-Script===&lt;br /&gt;
Em::Blocks stellt zwei fertige Linker-Scripts bereit, eins für die Ausführung des Programmes aus dem Flash (&#039;&#039;&#039;&#039;&#039;*_flash.ld&#039;&#039;&#039;&#039;&#039;), das andere für die Ausführung aus dem SRAM (&#039;&#039;&#039;&#039;&#039;*_sram.ld&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Normalerweise muss auch hier nichts geändert werden, es sei den Daten sollen in bestimmten Adressbereichen abgelegt werden (z.B. im Core-Coupled RAM), was ich später noch zum Tutorial hinzufüge.&lt;br /&gt;
&lt;br /&gt;
===Der Takt===&lt;br /&gt;
Jeder Controller oder Prozessor braucht einen Takt, indem er die einzelnen Maschinen-Befehle abarbeiten kann.&lt;br /&gt;
Bei den STM32 Mikrocontrollern kann dieser Takt aus verschiedenen Quellen kommen:&lt;br /&gt;
&lt;br /&gt;
1. High Speed Internal Oszillator (HSI)&lt;br /&gt;
&lt;br /&gt;
2. High Speed External Oszillator (HSE)&lt;br /&gt;
&lt;br /&gt;
3. Low Speed Internal Oszillator (LSI)&lt;br /&gt;
&lt;br /&gt;
4. Low Speed External Oszillator (LSE)&lt;br /&gt;
&lt;br /&gt;
5. Phase-Locked Loop (PLL) (generiert den Takt aus den ersten vier Taktquellen durch Teiler und Faktoren)&lt;br /&gt;
&lt;br /&gt;
Nach einem Reset wird der Controller aus der HSI Taktquelle versorgt (16MHz beim STM32F407VG). Um die voll Performance des Controllers zu erreichen muss die PLL verwendet werden, welche den Takt durch geschickte Teiler und Faktoren vervielfältigt, sodass am Ende der Controller mit der maximalen Taktfrequenz läuft. Die notwendige Initialisierung der PLL findet in der Funktion &#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; statt. Die PLL erzeugt zunächst einen Basistakt:&lt;br /&gt;
&lt;br /&gt;
PLL_VCO = (F_HSE / PLL_M) * PLL_N&lt;br /&gt;
&lt;br /&gt;
Aus diesem Takt wird dann der Takt für den Controller-Kern abgeleitet:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = PLL_VCO / PLL_P&lt;br /&gt;
&lt;br /&gt;
Und der Takt für SDIO / USB / RNG (48MHz):&lt;br /&gt;
&lt;br /&gt;
48MHz = PLL_VCO / PLL_Q&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Durch weiter Teiler werden, die Takte für die einzelnen Busse erzeugt, da diese nicht alle beliebig schnell betrieben werden dürfen.&lt;br /&gt;
&lt;br /&gt;
Genaue Angaben findet man zu dem jeweiligen Clock-System des Controllers im Reference Manual.&lt;br /&gt;
&lt;br /&gt;
Ein Blick in den &amp;quot;Kommentar-Header&amp;quot; verrät, dass von einem externen (HSE) Oszillator von 25MHz ausgegangen wird, der die PLL versorgen soll.&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((25MHz / PLL_M(25)) * PLL_N(336)) / PLL_P(2) = 168MHz&lt;br /&gt;
&lt;br /&gt;
Allerdings stimmt diese Rechnung natürlich nur, wenn wirklich ein 25MHz Quarz am Controller angeschlossen ist. Auf dem STM32F4-Discovery Board befindet sich aber nur ein 8MHz Quarz. Demnach gilt:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((8MHz / PLL_M(25)) * PLL_N(336)) / PLL_P(2) = 53.76MHz&lt;br /&gt;
&lt;br /&gt;
Der Controller läuft also nur mit 53.76MHz, wenn wie ober beschrieben ein Projekt erstellt wird. Allerdings kann dieses Problem durch ändern von den betroffen Defines behoben werden:&lt;br /&gt;
 &lt;br /&gt;
*Dazu geht man in die &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; Datei und passt zur Vollständigkeit erstmal die zum Controller passende Tabelle im &amp;quot;Kommentar-Header&amp;quot; an (Z.57f):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      HSE Frequency(Hz)                      | 8000000&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      PLL_M                                  | 8&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Danach passt man den PPL_M Define (Z.254) an:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/************************* PLL Parameters *************************************/&lt;br /&gt;
/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */&lt;br /&gt;
#define PLL_M      8&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Außerdem muss man den HSE_VALUE Define in der &#039;&#039;&#039;&#039;&#039;inc/stm32f4xx.h&#039;&#039;&#039;&#039;&#039; angepasst werden (Z.122):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#if !defined  (HSE_VALUE)&lt;br /&gt;
  #define HSE_VALUE    ((uint32_t)8000000) /*!&amp;lt; Value of the External oscillator in Hz */&lt;br /&gt;
&lt;br /&gt;
#endif /* HSE_VALUE */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine neue Berechnung zeigt:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((8MHz / PLL_M(8)) * PLL_N(336)) / PLL_P(2) = 168MHz&lt;br /&gt;
&lt;br /&gt;
Jetzt läuft der Controller mit maximaler Geschwindigkeit.&lt;br /&gt;
&lt;br /&gt;
Die Theorie wird durch folgendes Programm verifiziert. Der geviertelte System-Takt SYSCLK wir am Pin PC9 ausgegeben. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);&lt;br /&gt;
&lt;br /&gt;
    GPIO_InitTypeDef GPIOC_InitStructure;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Mode = GPIO_Mode_AF;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_OType = GPIO_OType_PP;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Pin = GPIO_Pin_9;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;&lt;br /&gt;
    GPIO_Init(GPIOC, &amp;amp;GPIOC_InitStructure);&lt;br /&gt;
&lt;br /&gt;
    RCC_MCO2Config(RCC_MCO2Source_SYSCLK, RCC_MCO2Div_4);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Die FPU===&lt;br /&gt;
====Allgemeines====&lt;br /&gt;
Damit die FPU richtig verwendet wird, müssen normalerweise zwei Bedingungen erfüllt sein:&lt;br /&gt;
&lt;br /&gt;
1. Der Controller muss in der Initialisierung-Funktion &#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; in &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; die FPU Hardware-seitig aktivieren&lt;br /&gt;
&lt;br /&gt;
2. Damit die FPU auch was zu tuen bekommt, müssen vom Compiler FPU-Instructions erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
Die Em::Blocks IDE verwendet standardmäßig die FPU, wenn eine Vorhanden ist. Hier wird die FPU Hardware-seitig aktiviert (&#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; Z.341):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* FPU settings ------------------------------------------------------------*/&lt;br /&gt;
  #if (__FPU_PRESENT == 1) &amp;amp;&amp;amp; (__FPU_USED == 1)&lt;br /&gt;
    SCB-&amp;gt;CPACR |= ((3UL &amp;lt;&amp;lt; 10*2)|(3UL &amp;lt;&amp;lt; 11*2));  /* set CP10 and CP11 Full Access */&lt;br /&gt;
  #endif&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
__FPU_PRESENT wird in der &#039;&#039;&#039;&#039;&#039;stm32f4xx.h&#039;&#039;&#039;&#039;&#039; definiert.&lt;br /&gt;
__FPU_USED wird von der IDE übernommen (siehe Build-Log): &#039;&#039;&#039;&#039;&#039;-D__FPU_USED&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Außerdem wird der Compiler von der IDE standardmäßig mit dem Argument &#039;&#039;&#039;&#039;&#039;-mfloat-abi=hard&#039;&#039;&#039;&#039;&#039; aufgerufen, wodurch FPU-Instructions erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
====FPU abschalten====&lt;br /&gt;
Um die FPU ab zu schalten (Mir würde jetzt nur Strom sparen als Grund einfallen) geht man wie folgt vor:&lt;br /&gt;
&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick Build options -&amp;gt; Device -&amp;gt; Policy&#039;&#039;&#039;&#039;&#039; wählt man &#039;&#039;&#039;&#039;&#039;Use target settings&#039;&#039;&#039;&#039;&#039; und über nimmt die Einstellungen, die vorher dort eingetragen waren, allerdings lässt man das Feld &#039;&#039;&#039;&#039;&#039;FP-hardware&#039;&#039;&#039;&#039;&#039; frei.&lt;br /&gt;
&lt;br /&gt;
[[Datei:fpu_1.png|FPU Abschalten Schritt 1]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;Compiler Settings -&amp;gt; Policy&#039;&#039;&#039;&#039;&#039; wählt man dann &#039;&#039;&#039;&#039;&#039;Use target options only&#039;&#039;&#039;&#039;&#039;. Dann kann man unter &#039;&#039;&#039;&#039;&#039;Categories&#039;&#039;&#039;&#039;&#039; die Option &#039;&#039;&#039;&#039;&#039;ARM FPU architecture&#039;&#039;&#039;&#039;&#039; auswählen. Dort stehen dann drei Möglichkeiten für die FPU zur Verfügung:&lt;br /&gt;
&lt;br /&gt;
1. Software-FPU-Library für Gleitkomma-Berechnung verwenden - Keine FPU-Instructions werden generiert (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=soft&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
2. Eine Mischung aus Software- und Hardware-FPU wird verwendet (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=softfp&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
3. Hardware-FPU wird für Gleitkomma-Berechnungen verwendet (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=hard&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
[[Datei:fpu_2.png|FPU Abschalten Schritt 2]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Um die FPU ab zu schalten wählt man natürlich die erste Möglichkeit.&lt;br /&gt;
Bei der 2. und 3. Möglichkeit fügt die IDE auch den Define &#039;&#039;&#039;&#039;&#039;__FPU_USED&#039;&#039;&#039;&#039;&#039; hinzu. Bei Der ersten Möglichkeit nicht. Der Code muss also nicht verändert / auskommentiert werden.&lt;br /&gt;
&lt;br /&gt;
Um die FPU wieder zu aktivieren müssen alle Schritte wieder rückgängig gemacht werden.&lt;br /&gt;
&lt;br /&gt;
Am besten ist es einfach mal alle Möglichkeiten im Einzelschritt durch zu probieren. Dann stellt man schnell fest, ob die FPU aktiviert wir oder nicht. Ein Blick in den erweiterten &#039;&#039;&#039;&#039;&#039;Build-Log&#039;&#039;&#039;&#039;&#039; gibt auch schnell Aufschluss darüber, wie der Compiler aufgerufen wird (siehe Kapitel [http://www.mikrocontroller.net/articles/STM32_-_Einstieg_mit_Em::Blocks#Compilieren Compilieren]).&lt;br /&gt;
&lt;br /&gt;
====Test Programm für die FPU====&lt;br /&gt;
Hier ein kleines Testprogramm, dass misst wie viele Taktzyklen für eine Gleitkomma-Multiplikation gebraucht werden. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define CORE_SysTickEn()    (*((u32*)0xE0001000)) = 0x40000001&lt;br /&gt;
#define CORE_SysTickDis()   (*((u32*)0xE0001000)) = 0x40000000&lt;br /&gt;
#define CORE_GetSysTick()   (*((u32*)0xE0001004))&lt;br /&gt;
&lt;br /&gt;
uint32_t t1, t2, dt;&lt;br /&gt;
float x, y, z;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    x = 53.64f;&lt;br /&gt;
    y = 0.27f;&lt;br /&gt;
&lt;br /&gt;
    CORE_SysTickEn();&lt;br /&gt;
    t1 = CORE_GetSysTick();&lt;br /&gt;
&lt;br /&gt;
    z = x * y;&lt;br /&gt;
&lt;br /&gt;
    t2 = CORE_GetSysTick();&lt;br /&gt;
    CORE_SysTickDis();&lt;br /&gt;
&lt;br /&gt;
    dt = (t2 - t1) - 9; //9 Takt-Zyklen werden für die Messung gebraucht &lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Compiler-Optimierung===&lt;br /&gt;
Standardmäßig verwendet Em::Blocks keine Optimierung. Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; Categories: Optimization&#039;&#039;&#039;&#039;&#039; kann zwischen verschieden Optimierungen ausgewählt werden.&lt;br /&gt;
&lt;br /&gt;
==Booten aus dem SRAM==&lt;br /&gt;
STM32 Controller haben die Möglichkeit Code aus dem Flash als auch aus dem SRAM auszuführen. Um eine Anwenung per Debugger in des SRAM zu laden sind nur wenige Schritte erforderlich:&lt;br /&gt;
&lt;br /&gt;
*Um das Linkerscript für den SRAM zu verwenden geht man zu: &#039;&#039;&#039;&#039;&#039;Build options... -&amp;gt; Device&#039;&#039;&#039;&#039;&#039; dort wählt man unter &#039;&#039;&#039;&#039;&#039;Policy&#039;&#039;&#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;Use target settings&#039;&#039;&#039;&#039;&#039; aus und übernimmt die vorherigen Einstellungen, nur unter &#039;&#039;&#039;&#039;&#039;Linker script*&#039;&#039;&#039;&#039;&#039; gibt man &#039;&#039;&#039;&#039;&#039;.\stm32f407vg_sram.ld&#039;&#039;&#039;&#039;&#039; an&lt;br /&gt;
&lt;br /&gt;
*Dann muss man noch unter &#039;&#039;&#039;&#039;&#039;Debug -&amp;gt; Interfaces -&amp;gt; Settings&#039;&#039;&#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;Vector table start&#039;&#039;&#039;&#039;&#039; auf 0x20000000 ändern und &#039;&#039;&#039;&#039;&#039;Execute from RAM&#039;&#039;&#039;&#039;&#039; auswählen.&lt;br /&gt;
&lt;br /&gt;
Anschließend kann man die Anwendung ganz normal debuggen. Nach einem Reset muss die Anwenung erneut mit dem Debugger gestartet werden.&lt;br /&gt;
&lt;br /&gt;
=Fortsetzung folgt..=&lt;br /&gt;
Kritik, Wünsche usw. sind gerne erwünscht, am besten hier in den Thread posten: [http://www.mikrocontroller.net/topic/323750 Neues STM32 Tutorial]&lt;br /&gt;
&lt;br /&gt;
[[Category:ARM]]&lt;br /&gt;
[[Category:STM32]]&lt;/div&gt;</summary>
		<author><name>Avrprogger</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=STM32_-_Einstieg_mit_Em::Blocks&amp;diff=81537</id>
		<title>STM32 - Einstieg mit Em::Blocks</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=STM32_-_Einstieg_mit_Em::Blocks&amp;diff=81537"/>
		<updated>2014-02-11T16:30:25Z</updated>

		<summary type="html">&lt;p&gt;Avrprogger: dfs&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In diesem Tutorial werde ich versuchen, möglichst einfach, die ersten Schritte zur Entwicklung von STM32 Anwenungen mit der Em::Blocks IDE zu erklären. Hier soll nicht so stark auf die einzelnen Peripherie-Module der Controller eingegangen werden, sondern mehr auf die IDE und die verschieden Libraries, wie die CMSIS Library, die DSP-Library, die Standard-Peripheral-Library, die USB-Library und vllt. über Ethernet. Ich denke ein Kapitel zu FreeRTOS wird es auch geben. Auserdem steht im Vordergrund Sachen wie z.B. booten aus dem SRAM, In-Application-Programming, FPU, Core-Coupled-RAM usw. Mal sehn wie weit ich komme ;)&lt;br /&gt;
&lt;br /&gt;
==Die Entwicklungsumgebung==&lt;br /&gt;
===Hardware===&lt;br /&gt;
Zum testen der Anwendungen, benutze ich das STM32F4-Discovery Board, welches einen Debugger, Peripherie und natürlich einen STM32 Controller (STM32F407VGT6) enthält. Deshalb sind alle Beispiele hier für den STM32F407VG Controller ausgelegt, können aber meisten 1:1 auf andere Controller portiert werden. Ich werde auch möglichsts keine STM32F4-Discovery Board spezifischen Libraries verwenden, damit der Portierungs-Vorgang möglichsts einfach bleibt.&lt;br /&gt;
&lt;br /&gt;
===Software===&lt;br /&gt;
In diesem Tutorial verwende ich [http://www.emblocks.org/ Em::Blocks] als IDE. Em::Blocks ist eine kostenlose, uneingeschränkte IDE, die alle STM32 Mikrcontroller unterstützt und sehr einfach zu bedienen ist.&lt;br /&gt;
nach dem Download kann die IDE per Dialog, sehr einfach, installiert werden. Als Compiler beinhaltet Em::Blocks den &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
Die IDE unterstützt zurzeit den ST-Link, den J-Link und es gibt eine Generic-Vorlage, durch welche andere Debugger konfiguriert werden können.&lt;br /&gt;
&lt;br /&gt;
Außerdem muss noch der passende Treiber für den Debugger installiert werden. Verwendet man ein Discovery-Board muss der [http://www.st.com/web/catalog/tools/FM146/CL1984/SC724/SS1677/PF251168 ST-Link/V2]-Treiber heruntergeladen und installiert werden. (Die Installation muss evtl. als Administrator ausgeführt werden, da sonst die Installation unvollständig wird.) Nach der Installation des Treibers kann man den Debugger über die entsprechende USB Schnittstelle an den PC anschließen und es sollte die Meldung von Windows kommen, dass der richtige Treiber gefunden wurde.&lt;br /&gt;
&lt;br /&gt;
===Libraries===&lt;br /&gt;
Zum programmieren benötigt man noch die [http://www.arm.com/products/processors/cortex-m/cortex-microcontroller-software-interface-standard.php CMSIS] und die Standard-Peripheral-Library (z.B. für die F4 Controller [http://www.st.com/stonline/stappl/productcatalog/app?page=partNumberSearchPage&amp;amp;levelid=SS1577&amp;amp;parentid=1743&amp;amp;resourcetype=SW Standard-Peripheral-Library-F4]), die man am besten in einen Ordner (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\STM32&#039;&#039;&#039;&#039;&#039;) entpackt&lt;br /&gt;
&lt;br /&gt;
==Basis-Wissen zur IDE==&lt;br /&gt;
Einige Grundfunktionalitäten der IDE:&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von Dateien zum Projekt===&lt;br /&gt;
Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf &amp;lt;ProjektName&amp;gt; -&amp;gt; Add files...&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Enfernen von Dateien aus dem Projekt===&lt;br /&gt;
Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf die Datei / mehrere Dateien auswählen -&amp;gt; Remove file from project&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
Die Dateien werden lediglich aus dem Projekt entfernt und nicht von der Festplatte gelöscht.&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von Include-Pfaden===&lt;br /&gt;
Sofern die Include-Datei(en) nicht im standard Include-Ordner &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; des Projektes liegen, muss man den Pfad zum Projekt hinzufügen, damit der Compiler die Include-Dateien später auch finden kann. Man geht wie folgt vor: Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf &amp;lt;ProjektName&amp;gt; -&amp;gt; Build options... -&amp;gt; Search Directories -&amp;gt; Add&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von globalen Defines zum Build===&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; #defines&#039;&#039;&#039;&#039;&#039; können globale Defines hinzugefügt werden.&lt;br /&gt;
&lt;br /&gt;
===Compilieren===&lt;br /&gt;
Entweder über das &#039;&#039;&#039;&#039;&#039;Build&#039;&#039;&#039;&#039;&#039; Menü oder über &#039;&#039;&#039;&#039;&#039;F7&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Um eine genau Ausgabe des Compiler-Aufrufes mit allen Argumenten zu bekommen, geht man im &#039;&#039;&#039;&#039;&#039;Settings&#039;&#039;&#039;&#039;&#039; Menü auf &#039;&#039;&#039;&#039;&#039;Tools...&#039;&#039;&#039;&#039;&#039; und dann auf &#039;&#039;&#039;&#039;&#039;Toolchain executables&#039;&#039;&#039;&#039;&#039;. Ganz unten, unter &#039;&#039;&#039;&#039;&#039;Logging&#039;&#039;&#039;&#039;&#039; kann man dann &#039;&#039;&#039;&#039;&#039;Full command line&#039;&#039;&#039;&#039;&#039; auswählen.&lt;br /&gt;
&lt;br /&gt;
===Debuggen===&lt;br /&gt;
*Als erstes den Debugger starten über das &#039;&#039;&#039;&#039;&#039;Debug&#039;&#039;&#039;&#039;&#039; Menü und &#039;&#039;&#039;&#039;&#039;Start/stop Debug Session&#039;&#039;&#039;&#039;&#039; oder über &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
*Danach läuft die Anwendung auf dem Controller und warten im &#039;&#039;&#039;&#039;&#039;Reset_Handler&#039;&#039;&#039;&#039;&#039; auf Einzelschritt- bzw. Run- Befehle (&#039;&#039;&#039;&#039;&#039;F5, F10, F11&#039;&#039;&#039;&#039;&#039; usw..(siehe &#039;&#039;&#039;&#039;&#039;Debug-Menü&#039;&#039;&#039;&#039;&#039; für alle Möglichkeiten))&lt;br /&gt;
&lt;br /&gt;
*Mit &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039; wird die Debug-Session auch wieder beendet&lt;br /&gt;
&lt;br /&gt;
*Unter &#039;&#039;&#039;&#039;&#039;Debug -&amp;gt; Interfaces -&amp;gt; Target settings&#039;&#039;&#039;&#039;&#039; können Eigenschaften, wie z.B &#039;&#039;&#039;&#039;&#039;Run to main()&#039;&#039;&#039;&#039;&#039; aktiviert werden.&lt;br /&gt;
&lt;br /&gt;
===Projekt als Template abspeichern===&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;File -&amp;gt; Save project as template...&#039;&#039;&#039;&#039;&#039;. Das Template erscheint dann im Projekt-Dialog unter &#039;&#039;&#039;&#039;&#039;User templates&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Das erste Projekt erstellen==&lt;br /&gt;
Hier erkläre ich, wie man am Besten (aus meiner Sicht), ein neues Projekt von Grund auf erstellt, sodass man hinterher, den Controller-Kern über die CMSIS-Library und die Peripherie über die Register steuern kann.&lt;br /&gt;
&lt;br /&gt;
===1. Projekt mit der IDE erstellen===&lt;br /&gt;
Nach der Installation der oben beschriebenen Komponenten erstellt man am besten ein Verzeichnis (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\EmBlocks&#039;&#039;&#039;&#039;&#039;), indem später alle Projekte gespeichert werden. Für Libraries kann man auch noch ein Verzeichnis (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\STM32&#039;&#039;&#039;&#039;&#039;) erstellen, wo alle Libraries gespeichert werden, die man für die Projekt brauchen.&lt;br /&gt;
&lt;br /&gt;
Als nächstes starten man EmBlocks. Bei dem ersten Start öffnet sich ein Fenster, wo verschiedene Compiler angezeigt werden, die Em::Blocks findet. Dort wählt man den &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039; aus und klickt &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039;. Nun sollte sich das Hauptfenster von Em::Blocks öffnen. Über &#039;&#039;&#039;&#039;&#039;Create a new Project&#039;&#039;&#039;&#039;&#039; oder &#039;&#039;&#039;&#039;&#039;File -&amp;gt; New -&amp;gt; Project&#039;&#039;&#039;&#039;&#039; ruft man den Projekt-Dialog auf und kann ein neues Projekt erzeugen.&lt;br /&gt;
&lt;br /&gt;
Auf der Ersten Seite wählen man den &#039;&#039;&#039;&#039;&#039;STmicro-ARM&#039;&#039;&#039;&#039;&#039; Projekt-Typ aus.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_1.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auf der nächsten Seite wird man darauf hingewiesen, dass das der entsprechende Projekt-Typ-Dialog ausgeführt wird. Hier kann man ein Häkchen bei &#039;&#039;&#039;&#039;&#039;Skip this page next time&#039;&#039;&#039;&#039;&#039; setzen und auf &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; klicken.&lt;br /&gt;
&lt;br /&gt;
Im nächsten Schritt wählen man das zuvor erstellt Verzeichnis unter &#039;&#039;&#039;&#039;&#039;Folder to create Project in&#039;&#039;&#039;&#039;&#039; aus, indem später alle Projekt gespeichert werden. Außerdem geben wir dem Projekt einen Namen (z.B. &#039;&#039;&#039;&#039;&#039;FirstProject&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_2.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danach muss man einen Compiler auswählen und bestimmen, welche Projekt-Konfigurationen erszeugt werden sollen. Unter &#039;&#039;&#039;&#039;&#039;Compiler&#039;&#039;&#039;&#039;&#039; wählt man &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039; und man kann das Häkchen bei &#039;&#039;&#039;&#039;&#039;Create &amp;quot;Release&amp;quot; configuration&#039;&#039;&#039;&#039;&#039; entfernen, da diese unnötig ist, die Debug-Konfiguration sollte eig. immer ausreichen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_3.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auf den folgenden Seite wird der Controller ausgewählt. Verwendet man ein STM32F4-Discovery Board müssen folgende Dinge gewählt werden: &#039;&#039;&#039;&#039;&#039;Cortex_M4 (F3xx - F4xx) -&amp;gt; STM32F4xx (Cortex M4 with FPU) -&amp;gt; STM32F407VG&#039;&#039;&#039;&#039;&#039;. Leider sind die Auswahl Möglichkeiten nicht ganz richtig, da auch die F3 Controller einen Cortex M4 Kern und eine FPU haben (Ist aber nicht so wichtig, ist nur eine formale Sache). Außerdem entfernt man das Häkchen bei &#039;&#039;&#039;&#039;&#039;Standard Peripherals Library&#039;&#039;&#039;&#039;&#039; (Wie man die Standard-Peripheral-Library einbindet und verwendet erkläre ich später). Man kann auch das Häkchen bei &#039;&#039;&#039;&#039;&#039;Create hex file for Realease target&#039;&#039;&#039;&#039;&#039; entfernen.&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;Stack Size&#039;&#039;&#039;&#039;&#039; und &#039;&#039;&#039;&#039;&#039;Heap Size&#039;&#039;&#039;&#039;&#039; wird die Größe von Stack und Heap festgelegt. Für eine erste Anwendung kann man die Einstellungen so lassen (Stack-Size: 0x0100 =&amp;gt; 256 Byte Stack und Heap-Size: 0x0000 =&amp;gt; kein Heap). Mit &#039;&#039;&#039;&#039;&#039;Finish&#039;&#039;&#039;&#039;&#039; ist der Projekt Dialog abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_4.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danach sollten sich zwei neue Fenster öffnen, um die Debug-Eigenschaften fest zu legen.&lt;br /&gt;
Verwendet man ein Discovery Board/ST-Link müssen die Einstellungen wie auf dem Bild gewählt werden. Über den Button &#039;&#039;&#039;&#039;&#039;Settings&#039;&#039;&#039;&#039;&#039; öffnet sich das zweite Fenster, falls sich dieses nicht schon von alleine öffnen sollte. Nach den Schließen der Fenster über &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; ist der Projekt Dialog beendet und ein neues Projekt steht zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_5_1.png|Debug Eigenschaften 1. Fenster]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_5_2.png|Debug Eigenschaften 2. Fenster]]&lt;br /&gt;
&lt;br /&gt;
===2. CMSIS-Library und Startup-Code hinzufügen===&lt;br /&gt;
Wenn man sich, nachdem man ein neues Projekt in der IDE erstellt hat, die bereits vorhandenen Dateien im Projekt ansieht, stellt man fest, das bereits ein Ordner &#039;&#039;&#039;&#039;&#039;cmsis&#039;&#039;&#039;&#039;&#039; existiert, der einige wichtige Include-Dateien der CMSIS-Library enthält. Allerdings sind das wirklich nur die wichtigsten Include-Dateien der CMSIS-Library und dazu noch, die aus einer älternen Version. Ich ziehe es deshalb vor die &amp;quot;Mini-CMSIS-Libraray&amp;quot; und die &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c/.h&#039;&#039;&#039;&#039;&#039; Dateien des Projektes durch aktuellere Versionen zu ersetzen. So ist später auch die Integration  von anderen Libraries, wie z.B. der CMSIS-DSP-Libarary einfacher.  &lt;br /&gt;
&lt;br /&gt;
Zunächst gehen man in das Projekt-Verzeichnis und löscht:&lt;br /&gt;
*Den Ordner &#039;&#039;&#039;&#039;&#039;cmsis&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Alle Dateien im Include Verzeichnis &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; im &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner&lt;br /&gt;
&lt;br /&gt;
Außerdem entfernt man auch alle gelöschten Dateien in der IDE aus dem Projekt mit &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Rechts Klick -&amp;gt; Remove file from project&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Es sollte folgende Verzeichnis Struktur überbleiben:&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_6.png|Überbleibende Dateien]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Jetzt müssen die gelöschten Dateien durch die aktuelleren ersetzt werden.&lt;br /&gt;
&lt;br /&gt;
*Dazu kopieren man den gesamten Ordner &#039;&#039;&#039;&#039;&#039;CMSIS&#039;&#039;&#039;&#039;&#039; aus dem CMSIS Download in das Projekt Verzeichnis.&lt;br /&gt;
&lt;br /&gt;
*Aus dem Standard-Peripheral-Library Download kopiert man von &#039;&#039;&#039;&#039;&#039;Libraries\CMSIS\Device\ST\STM32F4xx\Include&#039;&#039;&#039;&#039;&#039; alle Dateien in den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projekt Verzeichnisses&lt;br /&gt;
&lt;br /&gt;
*Aus der Standard-Peripheral-Library kopieren man ebenfalls von &#039;&#039;&#039;&#039;&#039;Libraries\CMSIS\Device\ST\STM32F4xx\Source\Templates&#039;&#039;&#039;&#039;&#039; die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; in den &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner des Projekts&lt;br /&gt;
&lt;br /&gt;
Anschließend müssen die neuen Dateien in der IDE dem Projekt hinzugefügt werden. Dazu benutzt man &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Rechts Klick -&amp;gt; Add files&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
*Aus dem &#039;&#039;&#039;&#039;&#039;CMSIS&#039;&#039;&#039;&#039;&#039; Ordner im Projekt Verzeichnis werden aus den Unterorder &#039;&#039;&#039;&#039;&#039;Include&#039;&#039;&#039;&#039;&#039; folgende Dateien dem Projekt hinzugefügt:&lt;br /&gt;
**arm_common_tables.h&lt;br /&gt;
**arm_const_structs.h&lt;br /&gt;
**arm_math.h&lt;br /&gt;
**core_cm4.h&lt;br /&gt;
**core_cm4_simd.h&lt;br /&gt;
**core_cmFunc.h&lt;br /&gt;
**core_cmInstr.h&lt;br /&gt;
*Alle Dateien aus den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projektes&lt;br /&gt;
*Die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; aus dem &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner&lt;br /&gt;
&lt;br /&gt;
So sollte die Struktur dann aussehen:&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_7.png|Anwenungs-Grundgerüst]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Da einige Dateien der Libraries später bearbeitet werden müssen und Schreibgeschützt sind, weise ich hier schonmal darauf hin, das der Schreibschutz in der IDE über &#039;&#039;&#039;&#039;&#039;Rechts Klick auf die Datei -&amp;gt; Properties -&amp;gt; Häkchen bei &amp;quot;File is read only&amp;quot; entfernen&#039;&#039;&#039;&#039;&#039; entfert werden kann.&lt;br /&gt;
&lt;br /&gt;
Damit die IDE die Header-Dateien der CMSIS Library auch finden kann, weil diese ja nicht im standard Include Ordner &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; liegen, muss unter &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Build Options -&amp;gt; Search Directories&#039;&#039;&#039;&#039;&#039; der Pfad &#039;&#039;&#039;&#039;&#039;CMSIS\Include&#039;&#039;&#039;&#039;&#039; hinzugefügt werden.&lt;br /&gt;
&lt;br /&gt;
Compiliert man jetzt das Projekt mit &#039;&#039;&#039;&#039;&#039;F7&#039;&#039;&#039;&#039;&#039; gibt es ein paar Fehler Meldungen, weil keine Controller-Reihe ausgewählt wurde. Ebenfalls unter &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Build Options -&amp;gt; Compiler Settings -&amp;gt; #defines&#039;&#039;&#039;&#039;&#039; wird der Define &#039;&#039;&#039;&#039;&#039;STM32F40_41xxx&#039;&#039;&#039;&#039;&#039; hinzugefügt.&lt;br /&gt;
&lt;br /&gt;
Beim erneuten Compilieren sollten sich nun keine neuen Fehler ergeben.&lt;br /&gt;
&lt;br /&gt;
===Das erste Programm===&lt;br /&gt;
Nachdem ein grundsätzliches &amp;quot;Gerüst&amp;quot; fertig ist, kann man den ersten Code schreiben.&lt;br /&gt;
main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC-&amp;gt;AHB1ENR |= RCC_AHB1ENR_GPIODEN;    //Takt für GPIO aktivieren&lt;br /&gt;
    GPIOD-&amp;gt;MODER |= GPIO_MODER_MODER15_0;   //GPIOD Pin15 als Ausgang&lt;br /&gt;
    GPIOD-&amp;gt;BSRRL |= GPIO_BSRR_BS_15;        //GPIOD Pin15 auf High ziehen&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039; wird dann der Debugger gestartet. Hat der Debugger das Projekt erfolgreich übertragen kann die Ausführung mit &#039;&#039;&#039;&#039;&#039;F5&#039;&#039;&#039;&#039;&#039; begonnen werden.&lt;br /&gt;
&lt;br /&gt;
==Libraries einbinden/verwenden==&lt;br /&gt;
===Einbinden der Standard-Peripheral-Library===&lt;br /&gt;
Um nicht immer die einzelnen Register, wie im ersten &amp;quot;bare-metal&amp;quot; Beispiel, aus dem Reference-Manual zu suchen und zu beschreiben, gibt es von ST die Standard Peripheral Library, die diese Aufgaben übernimmt und mit der sich die &amp;quot;normale/grundlegende&amp;quot; (Alles außer USB und Ethernet) Peripherie recht einfach steuern lässt. Um die Library zu verwenden erzeugt man wie oben beschrieben ein neues Grundgerüst und kopiert als erstes den Ordner &#039;&#039;&#039;&#039;&#039;Libraries\STM32F4xx_StdPeriph_Driver&#039;&#039;&#039;&#039;&#039; aus dem Standard-Peripheral-Library Download in das Projekt-Verzeichnis. Außerdem muss man die Datei &#039;&#039;&#039;&#039;&#039;Project\STM32F4xx_StdPeriph_Templates\stm32f4xx_conf.h&#039;&#039;&#039;&#039;&#039; ebenfalls aus dem Standard-Peripheral-Library Download in den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projektes kopieren. In der IDE fügt man den Include-Path &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\inc&#039;&#039;&#039;&#039;&#039; hinzufügen, wie bei der CMSIS-Library (s.o.).&lt;br /&gt;
Außerdem muss noch &#039;&#039;&#039;&#039;&#039;USE_STDPERIPH_DRIVER&#039;&#039;&#039;&#039;&#039; als Define in der IDE hinzugefügt werden (s.o.).&lt;br /&gt;
Danach fügt man die Source- und Include-Dateien aus dem Ordner &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\inc&#039;&#039;&#039;&#039;&#039; und &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\src&#039;&#039;&#039;&#039;&#039; dem Project mit &#039;&#039;&#039;&#039;&#039;&amp;lt;Project Name&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Add files&#039;&#039;&#039;&#039;&#039; hinzu, allerdings nur die, für welche auch der Controller die entsprechende Peripherie besitzt. Beim STM32F4-Discovery Board / STM32F407VG Controller dürfen also nicht folgende Dateien nicht mit hinzugefügt werden, weil diese Peripherie nur bei anderen Controller vorhanden ist:&lt;br /&gt;
&lt;br /&gt;
*stm32f4xx_dma2d.c/.h&lt;br /&gt;
*stm32f4xx_fmc.c/.h&lt;br /&gt;
*stm32f4xx_ltdc.c/.h&lt;br /&gt;
*stm32f4xx_sai.c/.h&lt;br /&gt;
&lt;br /&gt;
Daraus resultiert folgende Struktur:&lt;br /&gt;
&lt;br /&gt;
[[Datei:stdperiphlib_2.png|Header-Struktur]] [[Datei:stdperiphlib_1.png|Source-Struktur]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Anschließen kann die Standard-Peripheral-Library benutz werden.&lt;br /&gt;
main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);&lt;br /&gt;
&lt;br /&gt;
    GPIO_InitTypeDef GPIOD_InitStructure;&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Mode = GPIO_Mode_OUT;     //Als Ausgang&lt;br /&gt;
    GPIOD_InitStructure.GPIO_OType = GPIO_OType_PP;    //Push-Pull Betrieb&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Pin = GPIO_Pin_15;        //Pin 15 (STM32F4-Discovery: Blaue LED)&lt;br /&gt;
    GPIOD_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;  //Kein Pull-Up oder Pull-Down Widerstand aktiviert&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Speed = GPIO_Speed_25MHz; //25MHz Update-Rate&lt;br /&gt;
    GPIO_Init(GPIOD, &amp;amp;GPIOD_InitStructure);&lt;br /&gt;
&lt;br /&gt;
    GPIO_SetBits(GPIOD, GPIO_Pin_15);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Einbinden der DSP-Library===&lt;br /&gt;
STM32F3 / STM32F4 Microcontroller haben neben der FPU noch einen Digital-Signal-Processor (DSP). Die DSP dient hauptsächlich dazu, viele Daten schnell zu verarbeiten (z.B. Video- oder Audiosignal). Der CMSIS-Download beinhaltet dazu neben der eigentlichen CMSIS-Library auch noch eine DSP-Library. Diese Library stellt sowohl einfache, mathematische Funktionen wie addieren, multiplizieren usw. als auch komplexe Funktionen, wie z.B  einen IIR-Filter, zur Verfügung. Die DSP-Library ist weiter aufgeteilt in kleinere Module, wie z.B. BasicMathFunctions, FilteringFunctions usw. (siehe &#039;&#039;&#039;&#039;&#039;CMSIS\DSP-Library\Source&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
Um die DSP-Library zu verwenden müssen nur die Source-Files des benötigten Moduls einbinden.&lt;br /&gt;
(&#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Add files...&#039;&#039;&#039;&#039;&#039;). Außerdem muss in der &#039;&#039;&#039;&#039;&#039;main.c&#039;&#039;&#039;&#039;&#039; der Include &#039;&#039;&#039;&#039;&#039;arm_math.h&#039;&#039;&#039;&#039;&#039; eingebunden werden. Aus irgendeinem Grund gibt es dann jedoch die Warnung: &amp;quot;Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)&amp;quot;. Ich hab noch nicht rausgefunden, wieso diese Warnung auftaucht. Die Warnung verschwindet, wenn man in der &#039;&#039;&#039;&#039;&#039;Build options...&#039;&#039;&#039;&#039;&#039; das Define &#039;&#039;&#039;&#039;&#039;__FPU_PRESENT&#039;&#039;&#039;&#039;&#039; hinzufügt (Ich weiß selber das das keine schöne Lösung ist, eine andere hab ich jedoch noch nicht gefunden). Jetzt kann die DSP-Library verwedet werden. Das Beispiel multipliziert zwei Buffer miteinander. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
#include &amp;quot;arm_math.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    float32_t x[1024];&lt;br /&gt;
    float32_t y[1024];&lt;br /&gt;
    float32_t z[1024];&lt;br /&gt;
&lt;br /&gt;
    for(uint16_t i = 0; i &amp;lt; 1024; i++)&lt;br /&gt;
    {&lt;br /&gt;
        x[i] = i;&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for(uint16_t i = 0; i &amp;lt; 1024; i++)&lt;br /&gt;
    {&lt;br /&gt;
        y[i] = PI;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    arm_mult_f32(x, y, z, 1024);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Startup-Code, Linker-Script, Takt, FPU, Optimierung usw.==&lt;br /&gt;
===Startup-Code===&lt;br /&gt;
Em::Blocks fügt standardmäßig einen Startup-Code mit in das Projekt ein. Die wichtigsten Dinge die darin erledigt werden sind folgende:&lt;br /&gt;
&lt;br /&gt;
*Stack und Heap wird angelgt&lt;br /&gt;
*Die Vector-Table wird angelegt&lt;br /&gt;
*Ein Default Reset-Handler wird implementiert, dieser erledigt folgende aufgaben:&lt;br /&gt;
**Kopieren der definierten Daten aus dem Flash in den SRAM&lt;br /&gt;
**&#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; wird aufgerfen, wenn &#039;&#039;&#039;&#039;&#039;__NO_SYSTEM_INIT&#039;&#039;&#039;&#039;&#039; nicht definiert ist&lt;br /&gt;
**Sprung in die &#039;&#039;&#039;&#039;&#039;main()&#039;&#039;&#039;&#039;&#039; Funktion&lt;br /&gt;
*Allen anderen Interrupt-Handler wird eine Default-Funktion &#039;&#039;&#039;&#039;&#039;def_irq_handler&#039;&#039;&#039;&#039;&#039; mit einer &#039;&#039;&#039;&#039;&#039;while(1)&#039;&#039;&#039;&#039;&#039;-Schleife zugewiesen, falls kein anderer Interrupt-Handler existiert.&lt;br /&gt;
&lt;br /&gt;
Normalerweise muss am Startup-Code nichts verändert werden.&lt;br /&gt;
&lt;br /&gt;
===Linker-Script===&lt;br /&gt;
Em::Blocks stellt zwei fertige Linker-Scripts bereit, eins für die Ausführung des Programmes aus dem Flash (&#039;&#039;&#039;&#039;&#039;*_flash.ld&#039;&#039;&#039;&#039;&#039;), das andere für die Ausführung aus dem SRAM (&#039;&#039;&#039;&#039;&#039;*_sram.ld&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Normalerweise muss auch hier nichts geändert werden, es sei den Daten sollen in bestimmten Adressbereichen abgelegt werden (z.B. im Core-Coupled RAM), was ich später noch zum Tutorial hinzufüge.&lt;br /&gt;
&lt;br /&gt;
===Der Takt===&lt;br /&gt;
Jeder Controller oder Prozessor braucht einen Takt, indem er die einzelnen Maschinen-Befehle abarbeiten kann.&lt;br /&gt;
Bei den STM32 Mikrocontrollern kann dieser Takt aus verschiedenen Quellen kommen:&lt;br /&gt;
&lt;br /&gt;
1. High Speed Internal Oszillator (HSI)&lt;br /&gt;
&lt;br /&gt;
2. High Speed External Oszillator (HSE)&lt;br /&gt;
&lt;br /&gt;
3. Low Speed Internal Oszillator (LSI)&lt;br /&gt;
&lt;br /&gt;
4. Low Speed External Oszillator (LSE)&lt;br /&gt;
&lt;br /&gt;
5. Phase-Locked Loop (PLL) (generiert den Takt aus den ersten vier Taktquellen durch Teiler und Faktoren)&lt;br /&gt;
&lt;br /&gt;
Nach einem Reset wird der Controller aus der HSI Taktquelle versorgt (16MHz beim STM32F407VG). Um die voll Performance des Controllers zu erreichen muss die PLL verwendet werden, welche den Takt durch geschickte Teiler und Faktoren vervielfältigt, sodass am Ende der Controller mit der maximalen Taktfrequenz läuft. Die notwendige Initialisierung der PLL findet in der Funktion &#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; statt. Die PLL erzeugt zunächst einen Basistakt:&lt;br /&gt;
&lt;br /&gt;
PLL_VCO = (F_HSE / PLL_M) * PLL_N&lt;br /&gt;
&lt;br /&gt;
Aus diesem Takt wird dann der Takt für den Controller-Kern abgeleitet:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = PLL_VCO / PLL_P&lt;br /&gt;
&lt;br /&gt;
Und der Takt für SDIO / USB / RNG (48MHz):&lt;br /&gt;
&lt;br /&gt;
48MHz = PLL_VCO / PLL_Q&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Durch weiter Teiler werden, die Takte für die einzelnen Busse erzeugt, da diese nicht alle beliebig schnell betrieben werden dürfen.&lt;br /&gt;
&lt;br /&gt;
Genaue Angaben findet man zu dem jeweiligen Clock-System des Controllers im Reference Manual.&lt;br /&gt;
&lt;br /&gt;
Ein Blick in den &amp;quot;Kommentar-Header&amp;quot; verrät, dass von einem externen (HSE) Oszillator von 25MHz ausgegangen wird, der die PLL versorgen soll.&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((25MHz / PLL_M(25)) * PLL_N(336)) / PLL_P(2) = 168MHz&lt;br /&gt;
&lt;br /&gt;
Allerdings stimmt diese Rechnung natürlich nur, wenn wirklich ein 25MHz Quarz am Controller angeschlossen ist. Auf dem STM32F4-Discovery Board befindet sich aber nur ein 8MHz Quarz. Demnach gilt:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((8MHz / PLL_M(25)) * PLL_N(336)) / PLL_P(2) = 53.76MHz&lt;br /&gt;
&lt;br /&gt;
Der Controller läuft also nur mit 53.76MHz, wenn wie ober beschrieben ein Projekt erstellt wird. Allerdings kann dieses Problem durch ändern von den betroffen Defines behoben werden:&lt;br /&gt;
 &lt;br /&gt;
*Dazu geht man in die &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; Datei und passt zur Vollständigkeit erstmal die zum Controller passende Tabelle im &amp;quot;Kommentar-Header&amp;quot; an (Z.57f):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      HSE Frequency(Hz)                      | 8000000&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      PLL_M                                  | 8&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Danach passt man den PPL_M Define (Z.254) an:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/************************* PLL Parameters *************************************/&lt;br /&gt;
/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */&lt;br /&gt;
#define PLL_M      8&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Außerdem muss man den HSE_VALUE Define in der &#039;&#039;&#039;&#039;&#039;inc/stm32f4xx.h&#039;&#039;&#039;&#039;&#039; angepasst werden (Z.122):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#if !defined  (HSE_VALUE)&lt;br /&gt;
  #define HSE_VALUE    ((uint32_t)8000000) /*!&amp;lt; Value of the External oscillator in Hz */&lt;br /&gt;
&lt;br /&gt;
#endif /* HSE_VALUE */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine neue Berechnung zeigt:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((8MHz / PLL_M(8)) * PLL_N(336)) / PLL_P(2) = 168MHz&lt;br /&gt;
&lt;br /&gt;
Jetzt läuft der Controller mit maximaler Geschwindigkeit.&lt;br /&gt;
&lt;br /&gt;
Die Theorie wird durch folgendes Programm verifiziert. Der geviertelte System-Takt SYSCLK wir am Pin PC9 ausgegeben. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);&lt;br /&gt;
&lt;br /&gt;
    GPIO_InitTypeDef GPIOC_InitStructure;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Mode = GPIO_Mode_AF;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_OType = GPIO_OType_PP;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Pin = GPIO_Pin_9;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;&lt;br /&gt;
    GPIO_Init(GPIOC, &amp;amp;GPIOC_InitStructure);&lt;br /&gt;
&lt;br /&gt;
    RCC_MCO2Config(RCC_MCO2Source_SYSCLK, RCC_MCO2Div_4);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Die FPU===&lt;br /&gt;
====Allgemeines====&lt;br /&gt;
Damit die FPU richtig verwendet wird, müssen normalerweise zwei Bedingungen erfüllt sein:&lt;br /&gt;
&lt;br /&gt;
1. Der Controller muss in der Initialisierung-Funktion &#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; in &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; die FPU Hardware-seitig aktivieren&lt;br /&gt;
&lt;br /&gt;
2. Damit die FPU auch was zu tuen bekommt, müssen vom Compiler FPU-Instructions erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
Die Em::Blocks IDE verwendet standardmäßig die FPU, wenn eine Vorhanden ist. Hier wird die FPU Hardware-seitig aktiviert (&#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; Z.341):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* FPU settings ------------------------------------------------------------*/&lt;br /&gt;
  #if (__FPU_PRESENT == 1) &amp;amp;&amp;amp; (__FPU_USED == 1)&lt;br /&gt;
    SCB-&amp;gt;CPACR |= ((3UL &amp;lt;&amp;lt; 10*2)|(3UL &amp;lt;&amp;lt; 11*2));  /* set CP10 and CP11 Full Access */&lt;br /&gt;
  #endif&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
__FPU_PRESENT wird in der &#039;&#039;&#039;&#039;&#039;stm32f4xx.h&#039;&#039;&#039;&#039;&#039; definiert.&lt;br /&gt;
__FPU_USED wird von der IDE übernommen (siehe Build-Log): &#039;&#039;&#039;&#039;&#039;-D__FPU_USED&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Außerdem wird der Compiler von der IDE standardmäßig mit dem Argument &#039;&#039;&#039;&#039;&#039;-mfloat-abi=hard&#039;&#039;&#039;&#039;&#039; aufgerufen, wodurch FPU-Instructions erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
====FPU abschalten====&lt;br /&gt;
Um die FPU ab zu schalten (Mir würde jetzt nur Strom sparen als Grund einfallen) geht man wie folgt vor:&lt;br /&gt;
&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick Build options -&amp;gt; Device -&amp;gt; Policy&#039;&#039;&#039;&#039;&#039; wählt man &#039;&#039;&#039;&#039;&#039;Use target settings&#039;&#039;&#039;&#039;&#039; und über nimmt die Einstellungen, die vorher dort eingetragen waren, allerdings lässt man das Feld &#039;&#039;&#039;&#039;&#039;FP-hardware&#039;&#039;&#039;&#039;&#039; frei.&lt;br /&gt;
&lt;br /&gt;
[[Datei:fpu_1.png|FPU Abschalten Schritt 1]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;Compiler Settings -&amp;gt; Policy&#039;&#039;&#039;&#039;&#039; wählt man dann &#039;&#039;&#039;&#039;&#039;Use target options only&#039;&#039;&#039;&#039;&#039;. Dann kann man unter &#039;&#039;&#039;&#039;&#039;Categories&#039;&#039;&#039;&#039;&#039; die Option &#039;&#039;&#039;&#039;&#039;ARM FPU architecture&#039;&#039;&#039;&#039;&#039; auswählen. Dort stehen dann drei Möglichkeiten für die FPU zur Verfügung:&lt;br /&gt;
&lt;br /&gt;
1. Software-FPU-Library für Gleitkomma-Berechnung verwenden - Keine FPU-Instructions werden generiert (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=soft&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
2. Eine Mischung aus Software- und Hardware-FPU wird verwendet (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=softfp&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
3. Hardware-FPU wird für Gleitkomma-Berechnungen verwendet (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=hard&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
[[Datei:fpu_2.png|FPU Abschalten Schritt 2]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Um die FPU ab zu schalten wählt man natürlich die erste Möglichkeit.&lt;br /&gt;
Bei der 2. und 3. Möglichkeit fügt die IDE auch den Define &#039;&#039;&#039;&#039;&#039;__FPU_USED&#039;&#039;&#039;&#039;&#039; hinzu. Bei Der ersten Möglichkeit nicht. Der Code muss also nicht verändert / auskommentiert werden.&lt;br /&gt;
&lt;br /&gt;
Um die FPU wieder zu aktivieren müssen alle Schritte wieder rückgängig gemacht werden.&lt;br /&gt;
&lt;br /&gt;
Am besten ist es einfach mal alle Möglichkeiten im Einzelschritt durch zu probieren. Dann stellt man schnell fest, ob die FPU aktiviert wir oder nicht. Ein Blick in den erweiterten &#039;&#039;&#039;&#039;&#039;Build-Log&#039;&#039;&#039;&#039;&#039; gibt auch schnell Aufschluss darüber, wie der Compiler aufgerufen wird (siehe Kapitel [http://www.mikrocontroller.net/articles/STM32_-_Einstieg_mit_Em::Blocks#Compilieren Compilieren]).&lt;br /&gt;
&lt;br /&gt;
====Test Programm für die FPU====&lt;br /&gt;
Hier ein kleines Testprogramm, dass misst wie viele Taktzyklen für eine Gleitkomma-Multiplikation gebraucht werden. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define CORE_SysTickEn()    (*((u32*)0xE0001000)) = 0x40000001&lt;br /&gt;
#define CORE_SysTickDis()   (*((u32*)0xE0001000)) = 0x40000000&lt;br /&gt;
#define CORE_GetSysTick()   (*((u32*)0xE0001004))&lt;br /&gt;
&lt;br /&gt;
uint32_t t1, t2, dt;&lt;br /&gt;
float x, y, z;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    x = 53.64f;&lt;br /&gt;
    y = 0.27f;&lt;br /&gt;
&lt;br /&gt;
    CORE_SysTickEn();&lt;br /&gt;
    t1 = CORE_GetSysTick();&lt;br /&gt;
&lt;br /&gt;
    z = x * y;&lt;br /&gt;
&lt;br /&gt;
    t2 = CORE_GetSysTick();&lt;br /&gt;
    CORE_SysTickDis();&lt;br /&gt;
&lt;br /&gt;
    dt = (t2 - t1) - 9; //9 Takt-Zyklen werden für die Messung gebraucht &lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Compiler-Optimierung===&lt;br /&gt;
Standardmäßig verwendet Em::Blocks keine Optimierung. Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; Categories: Optimization&#039;&#039;&#039;&#039;&#039; kann zwischen verschieden Optimierungen ausgewählt werden.&lt;br /&gt;
&lt;br /&gt;
==Booten aus dem SRAM==&lt;br /&gt;
STM32 Controller haben die Möglichkeit Code aus dem Flash als auch aus dem SRAM auszuführen. Um eine Anwenung per Debugger in des SRAM zu laden sind nur wenige Schritte erforderlich:&lt;br /&gt;
&lt;br /&gt;
*Um das Linkerscript für den SRAM zu verwenden geht man zu: &#039;&#039;&#039;&#039;&#039;Build options... -&amp;gt; Device&#039;&#039;&#039;&#039;&#039; dort wählt man unter &#039;&#039;&#039;&#039;&#039;Policy&#039;&#039;&#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;Use target settings&#039;&#039;&#039;&#039;&#039; aus und übernimmt die vorherigen Einstellungen, nur unter &#039;&#039;&#039;&#039;&#039;Linker script*&#039;&#039;&#039;&#039;&#039; gibt man &#039;&#039;&#039;&#039;&#039;.\stm32f407vg_sram.ld&#039;&#039;&#039;&#039;&#039; an&lt;br /&gt;
&lt;br /&gt;
*Dann muss man noch unter &#039;&#039;&#039;&#039;&#039;Debug -&amp;gt; Interfaces -&amp;gt; Settings&#039;&#039;&#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;Vector table start&#039;&#039;&#039;&#039;&#039; auf 0x20000000 ändern und &#039;&#039;&#039;&#039;&#039;Execute from RAM&#039;&#039;&#039;&#039;&#039; auswählen.&lt;br /&gt;
&lt;br /&gt;
Anschließend kann man die Anwendung ganz normal debuggen. Nach einem Reset muss die Anwenung erneut mit dem Debugger gestartet werden.&lt;br /&gt;
&lt;br /&gt;
=Fortsetzung folgt..=&lt;br /&gt;
Kritik, Wünsche usw. sind gerne erwünscht, am besten hier in den Thread posten: [http://www.mikrocontroller.net/topic/323750 Neues STM32 Tutorial]&lt;br /&gt;
&lt;br /&gt;
[[Category:ARM]]&lt;br /&gt;
[[Category:STM32]]&lt;/div&gt;</summary>
		<author><name>Avrprogger</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=STM32_-_Einstieg_mit_Em::Blocks&amp;diff=81536</id>
		<title>STM32 - Einstieg mit Em::Blocks</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=STM32_-_Einstieg_mit_Em::Blocks&amp;diff=81536"/>
		<updated>2014-02-11T16:27:35Z</updated>

		<summary type="html">&lt;p&gt;Avrprogger: ghj&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In diesem Tutorial werde ich versuchen, möglichst einfach, die ersten Schritte zur Entwicklung von STM32 Anwenungen mit der Em::Blocks IDE zu erklären. Hier soll nicht so stark auf die einzelnen Peripherie-Module der Controller eingegangen werden, sondern mehr auf die IDE und die verschieden Libraries, wie die CMSIS Library, die DSP-Library, die Standard-Peripheral-Library, die USB-Library und vllt. über Ethernet. Ich denke ein Kapitel zu FreeRTOS wird es auch geben. Auserdem steht im Vordergrund Sachen wie z.B. booten aus dem SRAM, In-Application-Programming, FPU, Core-Coupled-RAM usw. Mal sehn wie weit ich komme ;)&lt;br /&gt;
&lt;br /&gt;
==Die Entwicklungsumgebung==&lt;br /&gt;
===Hardware===&lt;br /&gt;
Zum testen der Anwendungen, benutze ich das STM32F4-Discovery Board, welches einen Debugger, Peripherie und natürlich einen STM32 Controller (STM32F407VGT6) enthält. Deshalb sind alle Beispiele hier für den STM32F407VG Controller ausgelegt, können aber meisten 1:1 auf andere Controller portiert werden. Ich werde auch möglichsts keine STM32F4-Discovery Board spezifischen Libraries verwenden, damit der Portierungs-Vorgang möglichsts einfach bleibt.&lt;br /&gt;
&lt;br /&gt;
===Software===&lt;br /&gt;
In diesem Tutorial verwende ich [http://www.emblocks.org/ Em::Blocks] als IDE. Em::Blocks ist eine kostenlose, uneingeschränkte IDE, die alle STM32 Mikrcontroller unterstützt und sehr einfach zu bedienen ist.&lt;br /&gt;
nach dem Download kann die IDE per Dialog, sehr einfach, installiert werden. Als Compiler beinhaltet Em::Blocks den &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
Die IDE unterstützt zurzeit den ST-Link, den J-Link und es gibt eine Generic-Vorlage, durch welche andere Debugger konfiguriert werden können.&lt;br /&gt;
&lt;br /&gt;
Außerdem muss noch der passende Treiber für den Debugger installiert werden. Verwendet man ein Discovery-Board muss der [http://www.st.com/web/catalog/tools/FM146/CL1984/SC724/SS1677/PF251168 ST-Link/V2]-Treiber heruntergeladen und installiert werden. (Die Installation muss evtl. als Administrator ausgeführt werden, da sonst die Installation unvollständig wird.) Nach der Installation des Treibers kann man den Debugger über die entsprechende USB Schnittstelle an den PC anschließen und es sollte die Meldung von Windows kommen, dass der richtige Treiber gefunden wurde.&lt;br /&gt;
&lt;br /&gt;
===Libraries===&lt;br /&gt;
Zum programmieren benötigt man noch die [http://www.arm.com/products/processors/cortex-m/cortex-microcontroller-software-interface-standard.php CMSIS] und die Standard-Peripheral-Library (z.B. für die F4 Controller [http://www.st.com/stonline/stappl/productcatalog/app?page=partNumberSearchPage&amp;amp;levelid=SS1577&amp;amp;parentid=1743&amp;amp;resourcetype=SW Standard-Peripheral-Library-F4]), die man am besten in einen Ordner (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\STM32&#039;&#039;&#039;&#039;&#039;) entpackt&lt;br /&gt;
&lt;br /&gt;
==Basis-Wissen zur IDE==&lt;br /&gt;
Einige Grundfunktionalitäten der IDE:&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von Dateien zum Projekt===&lt;br /&gt;
Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf &amp;lt;ProjektName&amp;gt; -&amp;gt; Add files...&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Enfernen von Dateien aus dem Projekt===&lt;br /&gt;
Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf die Datei / mehrere Dateien auswählen -&amp;gt; Remove file from project&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
Die Dateien werden lediglich aus dem Projekt entfernt und nicht von der Festplatte gelöscht.&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von Include-Pfaden===&lt;br /&gt;
Sofern die Include-Datei(en) nicht im standard Include-Ordner &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; des Projektes liegen, muss man den Pfad zum Projekt hinzufügen, damit der Compiler die Include-Dateien später auch finden kann. Man geht wie folgt vor: Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf &amp;lt;ProjektName&amp;gt; -&amp;gt; Build options... -&amp;gt; Search Directories -&amp;gt; Add&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Compilieren===&lt;br /&gt;
Entweder über das &#039;&#039;&#039;&#039;&#039;Build&#039;&#039;&#039;&#039;&#039; Menü oder über &#039;&#039;&#039;&#039;&#039;F7&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Um eine genau Ausgabe des Compiler-Aufrufes mit allen Argumenten zu bekommen, geht man im &#039;&#039;&#039;&#039;&#039;Settings&#039;&#039;&#039;&#039;&#039; Menü auf &#039;&#039;&#039;&#039;&#039;Tools...&#039;&#039;&#039;&#039;&#039; und dann auf &#039;&#039;&#039;&#039;&#039;Toolchain executables&#039;&#039;&#039;&#039;&#039;. Ganz unten, unter &#039;&#039;&#039;&#039;&#039;Logging&#039;&#039;&#039;&#039;&#039; kann man dann &#039;&#039;&#039;&#039;&#039;Full command line&#039;&#039;&#039;&#039;&#039; auswählen.&lt;br /&gt;
&lt;br /&gt;
===Debuggen===&lt;br /&gt;
*Als erstes den Debugger starten über das &#039;&#039;&#039;&#039;&#039;Debug&#039;&#039;&#039;&#039;&#039; Menü und &#039;&#039;&#039;&#039;&#039;Start/stop Debug Session&#039;&#039;&#039;&#039;&#039; oder über &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
*Danach läuft die Anwendung auf dem Controller und warten im &#039;&#039;&#039;&#039;&#039;Reset_Handler&#039;&#039;&#039;&#039;&#039; auf Einzelschritt- bzw. Run- Befehle (&#039;&#039;&#039;&#039;&#039;F5, F10, F11&#039;&#039;&#039;&#039;&#039; usw..(siehe &#039;&#039;&#039;&#039;&#039;Debug-Menü&#039;&#039;&#039;&#039;&#039; für alle Möglichkeiten))&lt;br /&gt;
&lt;br /&gt;
*Mit &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039; wird die Debug-Session auch wieder beendet&lt;br /&gt;
&lt;br /&gt;
*Unter &#039;&#039;&#039;&#039;&#039;Debug -&amp;gt; Interfaces -&amp;gt; Target settings&#039;&#039;&#039;&#039;&#039; können Eigenschaften, wie z.B &#039;&#039;&#039;&#039;&#039;Run to main()&#039;&#039;&#039;&#039;&#039; aktiviert werden.&lt;br /&gt;
&lt;br /&gt;
===Projekt als Template abspeichern===&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;File -&amp;gt; Save project as template...&#039;&#039;&#039;&#039;&#039;. Das Template erscheint dann im Projekt-Dialog unter &#039;&#039;&#039;&#039;&#039;User templates&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Das erste Projekt erstellen==&lt;br /&gt;
Hier erkläre ich, wie man am Besten (aus meiner Sicht), ein neues Projekt von Grund auf erstellt, sodass man hinterher, den Controller-Kern über die CMSIS-Library und die Peripherie über die Register steuern kann.&lt;br /&gt;
&lt;br /&gt;
===1. Projekt mit der IDE erstellen===&lt;br /&gt;
Nach der Installation der oben beschriebenen Komponenten erstellt man am besten ein Verzeichnis (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\EmBlocks&#039;&#039;&#039;&#039;&#039;), indem später alle Projekte gespeichert werden. Für Libraries kann man auch noch ein Verzeichnis (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\STM32&#039;&#039;&#039;&#039;&#039;) erstellen, wo alle Libraries gespeichert werden, die man für die Projekt brauchen.&lt;br /&gt;
&lt;br /&gt;
Als nächstes starten man EmBlocks. Bei dem ersten Start öffnet sich ein Fenster, wo verschiedene Compiler angezeigt werden, die Em::Blocks findet. Dort wählt man den &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039; aus und klickt &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039;. Nun sollte sich das Hauptfenster von Em::Blocks öffnen. Über &#039;&#039;&#039;&#039;&#039;Create a new Project&#039;&#039;&#039;&#039;&#039; oder &#039;&#039;&#039;&#039;&#039;File -&amp;gt; New -&amp;gt; Project&#039;&#039;&#039;&#039;&#039; ruft man den Projekt-Dialog auf und kann ein neues Projekt erzeugen.&lt;br /&gt;
&lt;br /&gt;
Auf der Ersten Seite wählen man den &#039;&#039;&#039;&#039;&#039;STmicro-ARM&#039;&#039;&#039;&#039;&#039; Projekt-Typ aus.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_1.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auf der nächsten Seite wird man darauf hingewiesen, dass das der entsprechende Projekt-Typ-Dialog ausgeführt wird. Hier kann man ein Häkchen bei &#039;&#039;&#039;&#039;&#039;Skip this page next time&#039;&#039;&#039;&#039;&#039; setzen und auf &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; klicken.&lt;br /&gt;
&lt;br /&gt;
Im nächsten Schritt wählen man das zuvor erstellt Verzeichnis unter &#039;&#039;&#039;&#039;&#039;Folder to create Project in&#039;&#039;&#039;&#039;&#039; aus, indem später alle Projekt gespeichert werden. Außerdem geben wir dem Projekt einen Namen (z.B. &#039;&#039;&#039;&#039;&#039;FirstProject&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_2.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danach muss man einen Compiler auswählen und bestimmen, welche Projekt-Konfigurationen erszeugt werden sollen. Unter &#039;&#039;&#039;&#039;&#039;Compiler&#039;&#039;&#039;&#039;&#039; wählt man &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039; und man kann das Häkchen bei &#039;&#039;&#039;&#039;&#039;Create &amp;quot;Release&amp;quot; configuration&#039;&#039;&#039;&#039;&#039; entfernen, da diese unnötig ist, die Debug-Konfiguration sollte eig. immer ausreichen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_3.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auf den folgenden Seite wird der Controller ausgewählt. Verwendet man ein STM32F4-Discovery Board müssen folgende Dinge gewählt werden: &#039;&#039;&#039;&#039;&#039;Cortex_M4 (F3xx - F4xx) -&amp;gt; STM32F4xx (Cortex M4 with FPU) -&amp;gt; STM32F407VG&#039;&#039;&#039;&#039;&#039;. Leider sind die Auswahl Möglichkeiten nicht ganz richtig, da auch die F3 Controller einen Cortex M4 Kern und eine FPU haben (Ist aber nicht so wichtig, ist nur eine formale Sache). Außerdem entfernt man das Häkchen bei &#039;&#039;&#039;&#039;&#039;Standard Peripherals Library&#039;&#039;&#039;&#039;&#039; (Wie man die Standard-Peripheral-Library einbindet und verwendet erkläre ich später). Man kann auch das Häkchen bei &#039;&#039;&#039;&#039;&#039;Create hex file for Realease target&#039;&#039;&#039;&#039;&#039; entfernen.&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;Stack Size&#039;&#039;&#039;&#039;&#039; und &#039;&#039;&#039;&#039;&#039;Heap Size&#039;&#039;&#039;&#039;&#039; wird die Größe von Stack und Heap festgelegt. Für eine erste Anwendung kann man die Einstellungen so lassen (Stack-Size: 0x0100 =&amp;gt; 256 Byte Stack und Heap-Size: 0x0000 =&amp;gt; kein Heap). Mit &#039;&#039;&#039;&#039;&#039;Finish&#039;&#039;&#039;&#039;&#039; ist der Projekt Dialog abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_4.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danach sollten sich zwei neue Fenster öffnen, um die Debug-Eigenschaften fest zu legen.&lt;br /&gt;
Verwendet man ein Discovery Board/ST-Link müssen die Einstellungen wie auf dem Bild gewählt werden. Über den Button &#039;&#039;&#039;&#039;&#039;Settings&#039;&#039;&#039;&#039;&#039; öffnet sich das zweite Fenster, falls sich dieses nicht schon von alleine öffnen sollte. Nach den Schließen der Fenster über &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; ist der Projekt Dialog beendet und ein neues Projekt steht zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_5_1.png|Debug Eigenschaften 1. Fenster]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_5_2.png|Debug Eigenschaften 2. Fenster]]&lt;br /&gt;
&lt;br /&gt;
===2. CMSIS-Library und Startup-Code hinzufügen===&lt;br /&gt;
Wenn man sich, nachdem man ein neues Projekt in der IDE erstellt hat, die bereits vorhandenen Dateien im Projekt ansieht, stellt man fest, das bereits ein Ordner &#039;&#039;&#039;&#039;&#039;cmsis&#039;&#039;&#039;&#039;&#039; existiert, der einige wichtige Include-Dateien der CMSIS-Library enthält. Allerdings sind das wirklich nur die wichtigsten Include-Dateien der CMSIS-Library und dazu noch, die aus einer älternen Version. Ich ziehe es deshalb vor die &amp;quot;Mini-CMSIS-Libraray&amp;quot; und die &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c/.h&#039;&#039;&#039;&#039;&#039; Dateien des Projektes durch aktuellere Versionen zu ersetzen. So ist später auch die Integration  von anderen Libraries, wie z.B. der CMSIS-DSP-Libarary einfacher.  &lt;br /&gt;
&lt;br /&gt;
Zunächst gehen man in das Projekt-Verzeichnis und löscht:&lt;br /&gt;
*Den Ordner &#039;&#039;&#039;&#039;&#039;cmsis&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Alle Dateien im Include Verzeichnis &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; im &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner&lt;br /&gt;
&lt;br /&gt;
Außerdem entfernt man auch alle gelöschten Dateien in der IDE aus dem Projekt mit &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Rechts Klick -&amp;gt; Remove file from project&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Es sollte folgende Verzeichnis Struktur überbleiben:&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_6.png|Überbleibende Dateien]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Jetzt müssen die gelöschten Dateien durch die aktuelleren ersetzt werden.&lt;br /&gt;
&lt;br /&gt;
*Dazu kopieren man den gesamten Ordner &#039;&#039;&#039;&#039;&#039;CMSIS&#039;&#039;&#039;&#039;&#039; aus dem CMSIS Download in das Projekt Verzeichnis.&lt;br /&gt;
&lt;br /&gt;
*Aus dem Standard-Peripheral-Library Download kopiert man von &#039;&#039;&#039;&#039;&#039;Libraries\CMSIS\Device\ST\STM32F4xx\Include&#039;&#039;&#039;&#039;&#039; alle Dateien in den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projekt Verzeichnisses&lt;br /&gt;
&lt;br /&gt;
*Aus der Standard-Peripheral-Library kopieren man ebenfalls von &#039;&#039;&#039;&#039;&#039;Libraries\CMSIS\Device\ST\STM32F4xx\Source\Templates&#039;&#039;&#039;&#039;&#039; die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; in den &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner des Projekts&lt;br /&gt;
&lt;br /&gt;
Anschließend müssen die neuen Dateien in der IDE dem Projekt hinzugefügt werden. Dazu benutzt man &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Rechts Klick -&amp;gt; Add files&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
*Aus dem &#039;&#039;&#039;&#039;&#039;CMSIS&#039;&#039;&#039;&#039;&#039; Ordner im Projekt Verzeichnis werden aus den Unterorder &#039;&#039;&#039;&#039;&#039;Include&#039;&#039;&#039;&#039;&#039; folgende Dateien dem Projekt hinzugefügt:&lt;br /&gt;
**arm_common_tables.h&lt;br /&gt;
**arm_const_structs.h&lt;br /&gt;
**arm_math.h&lt;br /&gt;
**core_cm4.h&lt;br /&gt;
**core_cm4_simd.h&lt;br /&gt;
**core_cmFunc.h&lt;br /&gt;
**core_cmInstr.h&lt;br /&gt;
*Alle Dateien aus den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projektes&lt;br /&gt;
*Die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; aus dem &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner&lt;br /&gt;
&lt;br /&gt;
So sollte die Struktur dann aussehen:&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_7.png|Anwenungs-Grundgerüst]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Da einige Dateien der Libraries später bearbeitet werden müssen und Schreibgeschützt sind, weise ich hier schonmal darauf hin, das der Schreibschutz in der IDE über &#039;&#039;&#039;&#039;&#039;Rechts Klick auf die Datei -&amp;gt; Properties -&amp;gt; Häkchen bei &amp;quot;File is read only&amp;quot; entfernen&#039;&#039;&#039;&#039;&#039; entfert werden kann.&lt;br /&gt;
&lt;br /&gt;
Damit die IDE die Header-Dateien der CMSIS Library auch finden kann, weil diese ja nicht im standard Include Ordner &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; liegen, muss unter &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Build Options -&amp;gt; Search Directories&#039;&#039;&#039;&#039;&#039; der Pfad &#039;&#039;&#039;&#039;&#039;CMSIS\Include&#039;&#039;&#039;&#039;&#039; hinzugefügt werden.&lt;br /&gt;
&lt;br /&gt;
Compiliert man jetzt das Projekt mit &#039;&#039;&#039;&#039;&#039;F7&#039;&#039;&#039;&#039;&#039; gibt es ein paar Fehler Meldungen, weil keine Controller-Reihe ausgewählt wurde. Ebenfalls unter &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Build Options -&amp;gt; Compiler Settings -&amp;gt; #defines&#039;&#039;&#039;&#039;&#039; wird der Define &#039;&#039;&#039;&#039;&#039;STM32F40_41xxx&#039;&#039;&#039;&#039;&#039; hinzugefügt.&lt;br /&gt;
&lt;br /&gt;
Beim erneuten Compilieren sollten sich nun keine neuen Fehler ergeben.&lt;br /&gt;
&lt;br /&gt;
===Das erste Programm===&lt;br /&gt;
Nachdem ein grundsätzliches &amp;quot;Gerüst&amp;quot; fertig ist, kann man den ersten Code schreiben.&lt;br /&gt;
main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC-&amp;gt;AHB1ENR |= RCC_AHB1ENR_GPIODEN;    //Takt für GPIO aktivieren&lt;br /&gt;
    GPIOD-&amp;gt;MODER |= GPIO_MODER_MODER15_0;   //GPIOD Pin15 als Ausgang&lt;br /&gt;
    GPIOD-&amp;gt;BSRRL |= GPIO_BSRR_BS_15;        //GPIOD Pin15 auf High ziehen&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039; wird dann der Debugger gestartet. Hat der Debugger das Projekt erfolgreich übertragen kann die Ausführung mit &#039;&#039;&#039;&#039;&#039;F5&#039;&#039;&#039;&#039;&#039; begonnen werden.&lt;br /&gt;
&lt;br /&gt;
==Libraries einbinden/verwenden==&lt;br /&gt;
===Einbinden der Standard-Peripheral-Library===&lt;br /&gt;
Um nicht immer die einzelnen Register, wie im ersten &amp;quot;bare-metal&amp;quot; Beispiel, aus dem Reference-Manual zu suchen und zu beschreiben, gibt es von ST die Standard Peripheral Library, die diese Aufgaben übernimmt und mit der sich die &amp;quot;normale/grundlegende&amp;quot; (Alles außer USB und Ethernet) Peripherie recht einfach steuern lässt. Um die Library zu verwenden erzeugt man wie oben beschrieben ein neues Grundgerüst und kopiert als erstes den Ordner &#039;&#039;&#039;&#039;&#039;Libraries\STM32F4xx_StdPeriph_Driver&#039;&#039;&#039;&#039;&#039; aus dem Standard-Peripheral-Library Download in das Projekt-Verzeichnis. Außerdem muss man die Datei &#039;&#039;&#039;&#039;&#039;Project\STM32F4xx_StdPeriph_Templates\stm32f4xx_conf.h&#039;&#039;&#039;&#039;&#039; ebenfalls aus dem Standard-Peripheral-Library Download in den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projektes kopieren. In der IDE fügt man den Include-Path &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\inc&#039;&#039;&#039;&#039;&#039; hinzufügen, wie bei der CMSIS-Library (s.o.).&lt;br /&gt;
Außerdem muss noch &#039;&#039;&#039;&#039;&#039;USE_STDPERIPH_DRIVER&#039;&#039;&#039;&#039;&#039; als Define in der IDE hinzugefügt werden (s.o.).&lt;br /&gt;
Danach fügt man die Source- und Include-Dateien aus dem Ordner &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\inc&#039;&#039;&#039;&#039;&#039; und &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\src&#039;&#039;&#039;&#039;&#039; dem Project mit &#039;&#039;&#039;&#039;&#039;&amp;lt;Project Name&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Add files&#039;&#039;&#039;&#039;&#039; hinzu, allerdings nur die, für welche auch der Controller die entsprechende Peripherie besitzt. Beim STM32F4-Discovery Board / STM32F407VG Controller dürfen also nicht folgende Dateien nicht mit hinzugefügt werden, weil diese Peripherie nur bei anderen Controller vorhanden ist:&lt;br /&gt;
&lt;br /&gt;
*stm32f4xx_dma2d.c/.h&lt;br /&gt;
*stm32f4xx_fmc.c/.h&lt;br /&gt;
*stm32f4xx_ltdc.c/.h&lt;br /&gt;
*stm32f4xx_sai.c/.h&lt;br /&gt;
&lt;br /&gt;
Daraus resultiert folgende Struktur:&lt;br /&gt;
&lt;br /&gt;
[[Datei:stdperiphlib_2.png|Header-Struktur]] [[Datei:stdperiphlib_1.png|Source-Struktur]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Anschließen kann die Standard-Peripheral-Library benutz werden.&lt;br /&gt;
main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);&lt;br /&gt;
&lt;br /&gt;
    GPIO_InitTypeDef GPIOD_InitStructure;&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Mode = GPIO_Mode_OUT;     //Als Ausgang&lt;br /&gt;
    GPIOD_InitStructure.GPIO_OType = GPIO_OType_PP;    //Push-Pull Betrieb&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Pin = GPIO_Pin_15;        //Pin 15 (STM32F4-Discovery: Blaue LED)&lt;br /&gt;
    GPIOD_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;  //Kein Pull-Up oder Pull-Down Widerstand aktiviert&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Speed = GPIO_Speed_25MHz; //25MHz Update-Rate&lt;br /&gt;
    GPIO_Init(GPIOD, &amp;amp;GPIOD_InitStructure);&lt;br /&gt;
&lt;br /&gt;
    GPIO_SetBits(GPIOD, GPIO_Pin_15);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Einbinden der DSP-Library===&lt;br /&gt;
STM32F3 / STM32F4 Microcontroller haben neben der FPU noch einen Digital-Signal-Processor (DSP). Die DSP dient hauptsächlich dazu, viele Daten schnell zu verarbeiten (z.B. Video- oder Audiosignal). Der CMSIS-Download beinhaltet dazu neben der eigentlichen CMSIS-Library auch noch eine DSP-Library. Diese Library stellt sowohl einfache, mathematische Funktionen wie addieren, multiplizieren usw. als auch komplexe Funktionen, wie z.B  einen IIR-Filter, zur Verfügung. Die DSP-Library ist weiter aufgeteilt in kleinere Module, wie z.B. BasicMathFunctions, FilteringFunctions usw. (siehe &#039;&#039;&#039;&#039;&#039;CMSIS\DSP-Library\Source&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
Um die DSP-Library zu verwenden müssen nur die Source-Files des benötigten Moduls einbinden.&lt;br /&gt;
(&#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Add files...&#039;&#039;&#039;&#039;&#039;). Außerdem muss in der &#039;&#039;&#039;&#039;&#039;main.c&#039;&#039;&#039;&#039;&#039; der Include &#039;&#039;&#039;&#039;&#039;arm_math.h&#039;&#039;&#039;&#039;&#039; eingebunden werden. Aus irgendeinem Grund gibt es dann jedoch die Warnung: &amp;quot;Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)&amp;quot;. Ich hab noch nicht rausgefunden, wieso diese Warnung auftaucht. Die Warnung verschwindet, wenn man in der &#039;&#039;&#039;&#039;&#039;Build options...&#039;&#039;&#039;&#039;&#039; das Define &#039;&#039;&#039;&#039;&#039;__FPU_PRESENT&#039;&#039;&#039;&#039;&#039; hinzufügt (Ich weiß selber das das keine schöne Lösung ist, eine andere hab ich jedoch noch nicht gefunden). Jetzt kann die DSP-Library verwedet werden. Das Beispiel multipliziert zwei Buffer miteinander. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
#include &amp;quot;arm_math.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    float32_t x[1024];&lt;br /&gt;
    float32_t y[1024];&lt;br /&gt;
    float32_t z[1024];&lt;br /&gt;
&lt;br /&gt;
    for(uint16_t i = 0; i &amp;lt; 1024; i++)&lt;br /&gt;
    {&lt;br /&gt;
        x[i] = i;&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for(uint16_t i = 0; i &amp;lt; 1024; i++)&lt;br /&gt;
    {&lt;br /&gt;
        y[i] = PI;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    arm_mult_f32(x, y, z, 1024);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Startup-Code, Linker-Script, Takt, FPU, Optimierung usw.==&lt;br /&gt;
===Startup-Code===&lt;br /&gt;
Em::Blocks fügt standardmäßig einen Startup-Code mit in das Projekt ein. Die wichtigsten Dinge die darin erledigt werden sind folgende:&lt;br /&gt;
&lt;br /&gt;
*Stack und Heap wird angelgt&lt;br /&gt;
*Die Vector-Table wird angelegt&lt;br /&gt;
*Ein Default Reset-Handler wird implementiert, dieser erledigt folgende aufgaben:&lt;br /&gt;
**Kopieren der definierten Daten aus dem Flash in den SRAM&lt;br /&gt;
**&#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; wird aufgerfen, wenn &#039;&#039;&#039;&#039;&#039;__NO_SYSTEM_INIT&#039;&#039;&#039;&#039;&#039; nicht definiert ist&lt;br /&gt;
**Sprung in die &#039;&#039;&#039;&#039;&#039;main()&#039;&#039;&#039;&#039;&#039; Funktion&lt;br /&gt;
*Allen anderen Interrupt-Handler wird eine Default-Funktion &#039;&#039;&#039;&#039;&#039;def_irq_handler&#039;&#039;&#039;&#039;&#039; mit einer &#039;&#039;&#039;&#039;&#039;while(1)&#039;&#039;&#039;&#039;&#039;-Schleife zugewiesen, falls kein anderer Interrupt-Handler existiert.&lt;br /&gt;
&lt;br /&gt;
Normalerweise muss am Startup-Code nichts verändert werden.&lt;br /&gt;
&lt;br /&gt;
===Linker-Script===&lt;br /&gt;
Em::Blocks stellt zwei fertige Linker-Scripts bereit, eins für die Ausführung des Programmes aus dem Flash (&#039;&#039;&#039;&#039;&#039;*_flash.ld&#039;&#039;&#039;&#039;&#039;), das andere für die Ausführung aus dem SRAM (&#039;&#039;&#039;&#039;&#039;*_sram.ld&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Normalerweise muss auch hier nichts geändert werden, es sei den Daten sollen in bestimmten Adressbereichen abgelegt werden (z.B. im Core-Coupled RAM), was ich später noch zum Tutorial hinzufüge.&lt;br /&gt;
&lt;br /&gt;
===Der Takt===&lt;br /&gt;
Jeder Controller oder Prozessor braucht einen Takt, indem er die einzelnen Maschinen-Befehle abarbeiten kann.&lt;br /&gt;
Bei den STM32 Mikrocontrollern kann dieser Takt aus verschiedenen Quellen kommen:&lt;br /&gt;
&lt;br /&gt;
1. High Speed Internal Oszillator (HSI)&lt;br /&gt;
&lt;br /&gt;
2. High Speed External Oszillator (HSE)&lt;br /&gt;
&lt;br /&gt;
3. Low Speed Internal Oszillator (LSI)&lt;br /&gt;
&lt;br /&gt;
4. Low Speed External Oszillator (LSE)&lt;br /&gt;
&lt;br /&gt;
5. Phase-Locked Loop (PLL) (generiert den Takt aus den ersten vier Taktquellen durch Teiler und Faktoren)&lt;br /&gt;
&lt;br /&gt;
Nach einem Reset wird der Controller aus der HSI Taktquelle versorgt (16MHz beim STM32F407VG). Um die voll Performance des Controllers zu erreichen muss die PLL verwendet werden, welche den Takt durch geschickte Teiler und Faktoren vervielfältigt, sodass am Ende der Controller mit der maximalen Taktfrequenz läuft. Die notwendige Initialisierung der PLL findet in der Funktion &#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; statt. Die PLL erzeugt zunächst einen Basistakt:&lt;br /&gt;
&lt;br /&gt;
PLL_VCO = (F_HSE / PLL_M) * PLL_N&lt;br /&gt;
&lt;br /&gt;
Aus diesem Takt wird dann der Takt für den Controller-Kern abgeleitet:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = PLL_VCO / PLL_P&lt;br /&gt;
&lt;br /&gt;
Und der Takt für SDIO / USB / RNG (48MHz):&lt;br /&gt;
&lt;br /&gt;
48MHz = PLL_VCO / PLL_Q&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Durch weiter Teiler werden, die Takte für die einzelnen Busse erzeugt, da diese nicht alle beliebig schnell betrieben werden dürfen.&lt;br /&gt;
&lt;br /&gt;
Genaue Angaben findet man zu dem jeweiligen Clock-System des Controllers im Reference Manual.&lt;br /&gt;
&lt;br /&gt;
Ein Blick in den &amp;quot;Kommentar-Header&amp;quot; verrät, dass von einem externen (HSE) Oszillator von 25MHz ausgegangen wird, der die PLL versorgen soll.&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((25MHz / PLL_M(25)) * PLL_N(336)) / PLL_P(2) = 168MHz&lt;br /&gt;
&lt;br /&gt;
Allerdings stimmt diese Rechnung natürlich nur, wenn wirklich ein 25MHz Quarz am Controller angeschlossen ist. Auf dem STM32F4-Discovery Board befindet sich aber nur ein 8MHz Quarz. Demnach gilt:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((8MHz / PLL_M(25)) * PLL_N(336)) / PLL_P(2) = 53.76MHz&lt;br /&gt;
&lt;br /&gt;
Der Controller läuft also nur mit 53.76MHz, wenn wie ober beschrieben ein Projekt erstellt wird. Allerdings kann dieses Problem durch ändern von den betroffen Defines behoben werden:&lt;br /&gt;
 &lt;br /&gt;
*Dazu geht man in die &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; Datei und passt zur Vollständigkeit erstmal die zum Controller passende Tabelle im &amp;quot;Kommentar-Header&amp;quot; an (Z.57f):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      HSE Frequency(Hz)                      | 8000000&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      PLL_M                                  | 8&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Danach passt man den PPL_M Define (Z.254) an:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/************************* PLL Parameters *************************************/&lt;br /&gt;
/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */&lt;br /&gt;
#define PLL_M      8&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Außerdem muss man den HSE_VALUE Define in der &#039;&#039;&#039;&#039;&#039;inc/stm32f4xx.h&#039;&#039;&#039;&#039;&#039; angepasst werden (Z.122):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#if !defined  (HSE_VALUE)&lt;br /&gt;
  #define HSE_VALUE    ((uint32_t)8000000) /*!&amp;lt; Value of the External oscillator in Hz */&lt;br /&gt;
&lt;br /&gt;
#endif /* HSE_VALUE */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine neue Berechnung zeigt:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((8MHz / PLL_M(8)) * PLL_N(336)) / PLL_P(2) = 168MHz&lt;br /&gt;
&lt;br /&gt;
Jetzt läuft der Controller mit maximaler Geschwindigkeit.&lt;br /&gt;
&lt;br /&gt;
Die Theorie wird durch folgendes Programm verifiziert. Der geviertelte System-Takt SYSCLK wir am Pin PC9 ausgegeben. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);&lt;br /&gt;
&lt;br /&gt;
    GPIO_InitTypeDef GPIOC_InitStructure;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Mode = GPIO_Mode_AF;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_OType = GPIO_OType_PP;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Pin = GPIO_Pin_9;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;&lt;br /&gt;
    GPIO_Init(GPIOC, &amp;amp;GPIOC_InitStructure);&lt;br /&gt;
&lt;br /&gt;
    RCC_MCO2Config(RCC_MCO2Source_SYSCLK, RCC_MCO2Div_4);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Die FPU===&lt;br /&gt;
====Allgemeines====&lt;br /&gt;
Damit die FPU richtig verwendet wird, müssen normalerweise zwei Bedingungen erfüllt sein:&lt;br /&gt;
&lt;br /&gt;
1. Der Controller muss in der Initialisierung-Funktion &#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; in &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; die FPU Hardware-seitig aktivieren&lt;br /&gt;
&lt;br /&gt;
2. Damit die FPU auch was zu tuen bekommt, müssen vom Compiler FPU-Instructions erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
Die Em::Blocks IDE verwendet standardmäßig die FPU, wenn eine Vorhanden ist. Hier wird die FPU Hardware-seitig aktiviert (&#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; Z.341):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* FPU settings ------------------------------------------------------------*/&lt;br /&gt;
  #if (__FPU_PRESENT == 1) &amp;amp;&amp;amp; (__FPU_USED == 1)&lt;br /&gt;
    SCB-&amp;gt;CPACR |= ((3UL &amp;lt;&amp;lt; 10*2)|(3UL &amp;lt;&amp;lt; 11*2));  /* set CP10 and CP11 Full Access */&lt;br /&gt;
  #endif&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
__FPU_PRESENT wird in der &#039;&#039;&#039;&#039;&#039;stm32f4xx.h&#039;&#039;&#039;&#039;&#039; definiert.&lt;br /&gt;
__FPU_USED wird von der IDE übernommen (siehe Build-Log): &#039;&#039;&#039;&#039;&#039;-D__FPU_USED&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Außerdem wird der Compiler von der IDE standardmäßig mit dem Argument &#039;&#039;&#039;&#039;&#039;-mfloat-abi=hard&#039;&#039;&#039;&#039;&#039; aufgerufen, wodurch FPU-Instructions erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
====FPU abschalten====&lt;br /&gt;
Um die FPU ab zu schalten (Mir würde jetzt nur Strom sparen als Grund einfallen) geht man wie folgt vor:&lt;br /&gt;
&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick Build options -&amp;gt; Device -&amp;gt; Policy&#039;&#039;&#039;&#039;&#039; wählt man &#039;&#039;&#039;&#039;&#039;Use target settings&#039;&#039;&#039;&#039;&#039; und über nimmt die Einstellungen, die vorher dort eingetragen waren, allerdings lässt man das Feld &#039;&#039;&#039;&#039;&#039;FP-hardware&#039;&#039;&#039;&#039;&#039; frei.&lt;br /&gt;
&lt;br /&gt;
[[Datei:fpu_1.png|FPU Abschalten Schritt 1]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;Compiler Settings -&amp;gt; Policy&#039;&#039;&#039;&#039;&#039; wählt man dann &#039;&#039;&#039;&#039;&#039;Use target options only&#039;&#039;&#039;&#039;&#039;. Dann kann man unter &#039;&#039;&#039;&#039;&#039;Categories&#039;&#039;&#039;&#039;&#039; die Option &#039;&#039;&#039;&#039;&#039;ARM FPU architecture&#039;&#039;&#039;&#039;&#039; auswählen. Dort stehen dann drei Möglichkeiten für die FPU zur Verfügung:&lt;br /&gt;
&lt;br /&gt;
1. Software-FPU-Library für Gleitkomma-Berechnung verwenden - Keine FPU-Instructions werden generiert (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=soft&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
2. Eine Mischung aus Software- und Hardware-FPU wird verwendet (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=softfp&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
3. Hardware-FPU wird für Gleitkomma-Berechnungen verwendet (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=hard&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
[[Datei:fpu_2.png|FPU Abschalten Schritt 2]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Um die FPU ab zu schalten wählt man natürlich die erste Möglichkeit.&lt;br /&gt;
Bei der 2. und 3. Möglichkeit fügt die IDE auch den Define &#039;&#039;&#039;&#039;&#039;__FPU_USED&#039;&#039;&#039;&#039;&#039; hinzu. Bei Der ersten Möglichkeit nicht. Der Code muss also nicht verändert / auskommentiert werden.&lt;br /&gt;
&lt;br /&gt;
Um die FPU wieder zu aktivieren müssen alle Schritte wieder rückgängig gemacht werden.&lt;br /&gt;
&lt;br /&gt;
Am besten ist es einfach mal alle Möglichkeiten im Einzelschritt durch zu probieren. Dann stellt man schnell fest, ob die FPU aktiviert wir oder nicht. Ein Blick in den erweiterten &#039;&#039;&#039;&#039;&#039;Build-Log&#039;&#039;&#039;&#039;&#039; gibt auch schnell Aufschluss darüber, wie der Compiler aufgerufen wird (siehe Kapitel [http://www.mikrocontroller.net/articles/STM32_-_Einstieg_mit_Em::Blocks#Compilieren Compilieren]).&lt;br /&gt;
&lt;br /&gt;
====Test Programm für die FPU====&lt;br /&gt;
Hier ein kleines Testprogramm, dass misst wie viele Taktzyklen für eine Gleitkomma-Multiplikation gebraucht werden. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define CORE_SysTickEn()    (*((u32*)0xE0001000)) = 0x40000001&lt;br /&gt;
#define CORE_SysTickDis()   (*((u32*)0xE0001000)) = 0x40000000&lt;br /&gt;
#define CORE_GetSysTick()   (*((u32*)0xE0001004))&lt;br /&gt;
&lt;br /&gt;
uint32_t t1, t2, dt;&lt;br /&gt;
float x, y, z;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    x = 53.64f;&lt;br /&gt;
    y = 0.27f;&lt;br /&gt;
&lt;br /&gt;
    CORE_SysTickEn();&lt;br /&gt;
    t1 = CORE_GetSysTick();&lt;br /&gt;
&lt;br /&gt;
    z = x * y;&lt;br /&gt;
&lt;br /&gt;
    t2 = CORE_GetSysTick();&lt;br /&gt;
    CORE_SysTickDis();&lt;br /&gt;
&lt;br /&gt;
    dt = (t2 - t1) - 9; //9 Takt-Zyklen werden für die Messung gebraucht &lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Compiler-Optimierung===&lt;br /&gt;
Standardmäßig verwendet Em::Blocks keine Optimierung. Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; Categories: Optimization&#039;&#039;&#039;&#039;&#039; kann zwischen verschieden Optimierungen ausgewählt werden.&lt;br /&gt;
&lt;br /&gt;
==Booten aus dem SRAM==&lt;br /&gt;
STM32 Controller haben die Möglichkeit Code aus dem Flash als auch aus dem SRAM auszuführen. Um eine Anwenung per Debugger in des SRAM zu laden sind nur wenige Schritte erforderlich:&lt;br /&gt;
&lt;br /&gt;
*Um das Linkerscript für den SRAM zu verwenden geht man zu: &#039;&#039;&#039;&#039;&#039;Build options... -&amp;gt; Device&#039;&#039;&#039;&#039;&#039; dort wählt man unter &#039;&#039;&#039;&#039;&#039;Policy&#039;&#039;&#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;Use target settings&#039;&#039;&#039;&#039;&#039; aus und übernimmt die vorherigen Einstellungen, nur unter &#039;&#039;&#039;&#039;&#039;Linker script*&#039;&#039;&#039;&#039;&#039; gibt man &#039;&#039;&#039;&#039;&#039;.\stm32f407vg_sram.ld&#039;&#039;&#039;&#039;&#039; an&lt;br /&gt;
&lt;br /&gt;
*Dann muss man noch unter &#039;&#039;&#039;&#039;&#039;Debug -&amp;gt; Interfaces -&amp;gt; Settings&#039;&#039;&#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;Vector table start&#039;&#039;&#039;&#039;&#039; auf 0x20000000 ändern und &#039;&#039;&#039;&#039;&#039;Execute from RAM&#039;&#039;&#039;&#039;&#039; auswählen.&lt;br /&gt;
&lt;br /&gt;
Anschließend kann man die Anwendung ganz normal debuggen. Nach einem Reset muss die Anwenung erneut mit dem Debugger gestartet werden.&lt;br /&gt;
&lt;br /&gt;
=Fortsetzung folgt..=&lt;br /&gt;
Kritik, Wünsche usw. sind gerne erwünscht, am besten hier in den Thread posten: [http://www.mikrocontroller.net/topic/323750 Neues STM32 Tutorial]&lt;br /&gt;
&lt;br /&gt;
[[Category:ARM]]&lt;br /&gt;
[[Category:STM32]]&lt;/div&gt;</summary>
		<author><name>Avrprogger</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=STM32_-_Einstieg_mit_Em::Blocks&amp;diff=81535</id>
		<title>STM32 - Einstieg mit Em::Blocks</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=STM32_-_Einstieg_mit_Em::Blocks&amp;diff=81535"/>
		<updated>2014-02-11T16:26:45Z</updated>

		<summary type="html">&lt;p&gt;Avrprogger: ghj&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In diesem Tutorial werde ich versuchen, möglichst einfach, die ersten Schritte zur Entwicklung von STM32 Anwenungen mit der Em::Blocks IDE zu erklären. Hier soll nicht so stark auf die einzelnen Peripherie-Module der Controller eingegangen werden, sondern mehr auf die IDE und die verschieden Libraries, wie die CMSIS Library, die DSP-Library, die Standard-Peripheral-Library, die USB-Library und vllt. über Ethernet. Ich denke ein Kapitel zu FreeRTOS wird es auch geben. Auserdem steht im Vordergrund Sachen wie z.B. booten aus dem SRAM, In-Application-Programming, FPU, Core-Coupled-RAM usw. Mal sehn wie weit ich komme ;)&lt;br /&gt;
&lt;br /&gt;
==Die Entwicklungsumgebung==&lt;br /&gt;
===Hardware===&lt;br /&gt;
Zum testen der Anwendungen, benutze ich das STM32F4-Discovery Board, welches einen Debugger, Peripherie und natürlich einen STM32 Controller (STM32F407VGT6) enthält. Deshalb sind alle Beispiele hier für den STM32F407VG Controller ausgelegt, können aber meisten 1:1 auf andere Controller portiert werden. Ich werde auch möglichsts keine STM32F4-Discovery Board spezifischen Libraries verwenden, damit der Portierungs-Vorgang möglichsts einfach bleibt.&lt;br /&gt;
&lt;br /&gt;
===Software===&lt;br /&gt;
In diesem Tutorial verwende ich [http://www.emblocks.org/ Em::Blocks] als IDE. Em::Blocks ist eine kostenlose, uneingeschränkte IDE, die alle STM32 Mikrcontroller unterstützt und sehr einfach zu bedienen ist.&lt;br /&gt;
nach dem Download kann die IDE per Dialog, sehr einfach, installiert werden. Als Compiler beinhaltet Em::Blocks den &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
Die IDE unterstützt zurzeit den ST-Link, den J-Link und es gibt eine Generic-Vorlage, durch welche andere Debugger konfiguriert werden können.&lt;br /&gt;
&lt;br /&gt;
Außerdem muss noch der passende Treiber für den Debugger installiert werden. Verwendet man ein Discovery-Board muss der [http://www.st.com/web/catalog/tools/FM146/CL1984/SC724/SS1677/PF251168 ST-Link/V2]-Treiber heruntergeladen und installiert werden. (Die Installation muss evtl. als Administrator ausgeführt werden, da sonst die Installation unvollständig wird.) Nach der Installation des Treibers kann man den Debugger über die entsprechende USB Schnittstelle an den PC anschließen und es sollte die Meldung von Windows kommen, dass der richtige Treiber gefunden wurde.&lt;br /&gt;
&lt;br /&gt;
===Libraries===&lt;br /&gt;
Zum programmieren benötigt man noch die [http://www.arm.com/products/processors/cortex-m/cortex-microcontroller-software-interface-standard.php CMSIS] und die Standard-Peripheral-Library (z.B. für die F4 Controller [http://www.st.com/stonline/stappl/productcatalog/app?page=partNumberSearchPage&amp;amp;levelid=SS1577&amp;amp;parentid=1743&amp;amp;resourcetype=SW Standard-Peripheral-Library-F4]), die man am besten in einen Ordner (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\STM32&#039;&#039;&#039;&#039;&#039;) entpackt&lt;br /&gt;
&lt;br /&gt;
==Basis-Wissen zur IDE==&lt;br /&gt;
Einige Grundfunktionalitäten der IDE:&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von Dateien zum Projekt===&lt;br /&gt;
Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf &amp;lt;ProjektName&amp;gt; -&amp;gt; Add files...&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Enfernen von Dateien aus dem Projekt===&lt;br /&gt;
Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf die Datei / mehrere Dateien auswählen -&amp;gt; Remove file from project&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
Die Dateien werden lediglich aus dem Projekt entfernt und nicht von der Festplatte gelöscht.&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von Include-Pfaden===&lt;br /&gt;
Sofern die Include-Datei(en) nicht im standard Include-Ordner &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; des Projektes liegen, muss man den Pfad zum Projekt hinzufügen, damit der Compiler die Include-Dateien später auch finden kann. Man geht wie folgt vor: Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf &amp;lt;ProjektName&amp;gt; -&amp;gt; Build options... -&amp;gt; Search Directories -&amp;gt; Add&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Compilieren===&lt;br /&gt;
Entweder über das &#039;&#039;&#039;&#039;&#039;Build&#039;&#039;&#039;&#039;&#039; Menü oder über &#039;&#039;&#039;&#039;&#039;F7&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Um eine genau Ausgabe des Compiler-Aufrufes mit allen Argumenten zu bekommen, geht man im &#039;&#039;&#039;&#039;&#039;Settings&#039;&#039;&#039;&#039;&#039; Menü auf &#039;&#039;&#039;&#039;&#039;Tools...&#039;&#039;&#039;&#039;&#039; und dann auf &#039;&#039;&#039;&#039;&#039;Toolchain executables&#039;&#039;&#039;&#039;&#039;. Ganz unten, unter &#039;&#039;&#039;&#039;&#039;Logging&#039;&#039;&#039;&#039;&#039; kann man dann &#039;&#039;&#039;&#039;&#039;Full command line&#039;&#039;&#039;&#039;&#039; auswählen.&lt;br /&gt;
&lt;br /&gt;
===Debuggen===&lt;br /&gt;
*Als erstes den Debugger starten über das &#039;&#039;&#039;&#039;&#039;Debug&#039;&#039;&#039;&#039;&#039; Menü und &#039;&#039;&#039;&#039;&#039;Start/stop Debug Session&#039;&#039;&#039;&#039;&#039; oder über &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
*Danach läuft die Anwendung auf dem Controller und warten im &#039;&#039;&#039;&#039;&#039;Reset_Handler&#039;&#039;&#039;&#039;&#039; auf Einzelschritt- bzw. Run- Befehle (&#039;&#039;&#039;&#039;&#039;F5, F10, F11&#039;&#039;&#039;&#039;&#039; usw..(siehe &#039;&#039;&#039;&#039;&#039;Debug-Menü&#039;&#039;&#039;&#039;&#039; für alle Möglichkeiten))&lt;br /&gt;
&lt;br /&gt;
*Mit &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039; wird die Debug-Session auch wieder beendet&lt;br /&gt;
&lt;br /&gt;
*Unter &#039;&#039;&#039;&#039;&#039;Debug -&amp;gt; Interfaces -&amp;gt; Target settings&#039;&#039;&#039;&#039;&#039; können Eigenschaften, wie z.B &#039;&#039;&#039;&#039;&#039;Run to main()&#039;&#039;&#039;&#039;&#039; aktiviert werden.&lt;br /&gt;
&lt;br /&gt;
===Projekt als Template abspeichern===&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;File -&amp;gt; Save project as template...&#039;&#039;&#039;&#039;&#039;. Das Template erscheint dann im Projekt-Dialog unter &#039;&#039;&#039;&#039;&#039;User templates&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Das erste Projekt erstellen==&lt;br /&gt;
Hier erkläre ich, wie man am Besten (aus meiner Sicht), ein neues Projekt von Grund auf erstellt, sodass man hinterher, den Controller-Kern über die CMSIS-Library und die Peripherie über die Register steuern kann.&lt;br /&gt;
&lt;br /&gt;
===1. Projekt mit der IDE erstellen===&lt;br /&gt;
Nach der Installation der oben beschriebenen Komponenten erstellt man am besten ein Verzeichnis (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\EmBlocks&#039;&#039;&#039;&#039;&#039;), indem später alle Projekte gespeichert werden. Für Libraries kann man auch noch ein Verzeichnis (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\STM32&#039;&#039;&#039;&#039;&#039;) erstellen, wo alle Libraries gespeichert werden, die man für die Projekt brauchen.&lt;br /&gt;
&lt;br /&gt;
Als nächstes starten man EmBlocks. Bei dem ersten Start öffnet sich ein Fenster, wo verschiedene Compiler angezeigt werden, die Em::Blocks findet. Dort wählt man den &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039; aus und klickt &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039;. Nun sollte sich das Hauptfenster von Em::Blocks öffnen. Über &#039;&#039;&#039;&#039;&#039;Create a new Project&#039;&#039;&#039;&#039;&#039; oder &#039;&#039;&#039;&#039;&#039;File -&amp;gt; New -&amp;gt; Project&#039;&#039;&#039;&#039;&#039; ruft man den Projekt-Dialog auf und kann ein neues Projekt erzeugen.&lt;br /&gt;
&lt;br /&gt;
Auf der Ersten Seite wählen man den &#039;&#039;&#039;&#039;&#039;STmicro-ARM&#039;&#039;&#039;&#039;&#039; Projekt-Typ aus.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_1.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auf der nächsten Seite wird man darauf hingewiesen, dass das der entsprechende Projekt-Typ-Dialog ausgeführt wird. Hier kann man ein Häkchen bei &#039;&#039;&#039;&#039;&#039;Skip this page next time&#039;&#039;&#039;&#039;&#039; setzen und auf &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; klicken.&lt;br /&gt;
&lt;br /&gt;
Im nächsten Schritt wählen man das zuvor erstellt Verzeichnis unter &#039;&#039;&#039;&#039;&#039;Folder to create Project in&#039;&#039;&#039;&#039;&#039; aus, indem später alle Projekt gespeichert werden. Außerdem geben wir dem Projekt einen Namen (z.B. &#039;&#039;&#039;&#039;&#039;FirstProject&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_2.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danach muss man einen Compiler auswählen und bestimmen, welche Projekt-Konfigurationen erszeugt werden sollen. Unter &#039;&#039;&#039;&#039;&#039;Compiler&#039;&#039;&#039;&#039;&#039; wählt man &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039; und man kann das Häkchen bei &#039;&#039;&#039;&#039;&#039;Create &amp;quot;Release&amp;quot; configuration&#039;&#039;&#039;&#039;&#039; entfernen, da diese unnötig ist, die Debug-Konfiguration sollte eig. immer ausreichen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_3.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auf den folgenden Seite wird der Controller ausgewählt. Verwendet man ein STM32F4-Discovery Board müssen folgende Dinge gewählt werden: &#039;&#039;&#039;&#039;&#039;Cortex_M4 (F3xx - F4xx) -&amp;gt; STM32F4xx (Cortex M4 with FPU) -&amp;gt; STM32F407VG&#039;&#039;&#039;&#039;&#039;. Leider sind die Auswahl Möglichkeiten nicht ganz richtig, da auch die F3 Controller einen Cortex M4 Kern und eine FPU haben (Ist aber nicht so wichtig, ist nur eine formale Sache). Außerdem entfernt man das Häkchen bei &#039;&#039;&#039;&#039;&#039;Standard Peripherals Library&#039;&#039;&#039;&#039;&#039; (Wie man die Standard-Peripheral-Library einbindet und verwendet erkläre ich später). Man kann auch das Häkchen bei &#039;&#039;&#039;&#039;&#039;Create hex file for Realease target&#039;&#039;&#039;&#039;&#039; entfernen.&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;Stack Size&#039;&#039;&#039;&#039;&#039; und &#039;&#039;&#039;&#039;&#039;Heap Size&#039;&#039;&#039;&#039;&#039; wird die Größe von Stack und Heap festgelegt. Für eine erste Anwendung kann man die Einstellungen so lassen (Stack-Size: 0x0100 =&amp;gt; 256 Byte Stack und Heap-Size: 0x0000 =&amp;gt; kein Heap). Mit &#039;&#039;&#039;&#039;&#039;Finish&#039;&#039;&#039;&#039;&#039; ist der Projekt Dialog abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_4.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danach sollten sich zwei neue Fenster öffnen, um die Debug-Eigenschaften fest zu legen.&lt;br /&gt;
Verwendet man ein Discovery Board/ST-Link müssen die Einstellungen wie auf dem Bild gewählt werden. Über den Button &#039;&#039;&#039;&#039;&#039;Settings&#039;&#039;&#039;&#039;&#039; öffnet sich das zweite Fenster, falls sich dieses nicht schon von alleine öffnen sollte. Nach den Schließen der Fenster über &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; ist der Projekt Dialog beendet und ein neues Projekt steht zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_5_1.png|Debug Eigenschaften 1. Fenster]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_5_2.png|Debug Eigenschaften 2. Fenster]]&lt;br /&gt;
&lt;br /&gt;
===2. CMSIS-Library und Startup-Code hinzufügen===&lt;br /&gt;
Wenn man sich, nachdem man ein neues Projekt in der IDE erstellt hat, die bereits vorhandenen Dateien im Projekt ansieht, stellt man fest, das bereits ein Ordner &#039;&#039;&#039;&#039;&#039;cmsis&#039;&#039;&#039;&#039;&#039; existiert, der einige wichtige Include-Dateien der CMSIS-Library enthält. Allerdings sind das wirklich nur die wichtigsten Include-Dateien der CMSIS-Library und dazu noch, die aus einer älternen Version. Ich ziehe es deshalb vor die &amp;quot;Mini-CMSIS-Libraray&amp;quot; und die &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c/.h&#039;&#039;&#039;&#039;&#039; Dateien des Projektes durch aktuellere Versionen zu ersetzen. So ist später auch die Integration  von anderen Libraries, wie z.B. der CMSIS-DSP-Libarary einfacher.  &lt;br /&gt;
&lt;br /&gt;
Zunächst gehen man in das Projekt-Verzeichnis und löscht:&lt;br /&gt;
*Den Ordner &#039;&#039;&#039;&#039;&#039;cmsis&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Alle Dateien im Include Verzeichnis &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; im &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner&lt;br /&gt;
&lt;br /&gt;
Außerdem entfernt man auch alle gelöschten Dateien in der IDE aus dem Projekt mit &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Rechts Klick -&amp;gt; Remove file from project&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Es sollte folgende Verzeichnis Struktur überbleiben:&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_6.png|Überbleibende Dateien]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Jetzt müssen die gelöschten Dateien durch die aktuelleren ersetzt werden.&lt;br /&gt;
&lt;br /&gt;
*Dazu kopieren man den gesamten Ordner &#039;&#039;&#039;&#039;&#039;CMSIS&#039;&#039;&#039;&#039;&#039; aus dem CMSIS Download in das Projekt Verzeichnis.&lt;br /&gt;
&lt;br /&gt;
*Aus dem Standard-Peripheral-Library Download kopiert man von &#039;&#039;&#039;&#039;&#039;Libraries\CMSIS\Device\ST\STM32F4xx\Include&#039;&#039;&#039;&#039;&#039; alle Dateien in den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projekt Verzeichnisses&lt;br /&gt;
&lt;br /&gt;
*Aus der Standard-Peripheral-Library kopieren man ebenfalls von &#039;&#039;&#039;&#039;&#039;Libraries\CMSIS\Device\ST\STM32F4xx\Source\Templates&#039;&#039;&#039;&#039;&#039; die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; in den &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner des Projekts&lt;br /&gt;
&lt;br /&gt;
Anschließend müssen die neuen Dateien in der IDE dem Projekt hinzugefügt werden. Dazu benutzt man &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Rechts Klick -&amp;gt; Add files&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
*Aus dem &#039;&#039;&#039;&#039;&#039;CMSIS&#039;&#039;&#039;&#039;&#039; Ordner im Projekt Verzeichnis werden aus den Unterorder &#039;&#039;&#039;&#039;&#039;Include&#039;&#039;&#039;&#039;&#039; folgende Dateien dem Projekt hinzugefügt:&lt;br /&gt;
**arm_common_tables.h&lt;br /&gt;
**arm_const_structs.h&lt;br /&gt;
**arm_math.h&lt;br /&gt;
**core_cm4.h&lt;br /&gt;
**core_cm4_simd.h&lt;br /&gt;
**core_cmFunc.h&lt;br /&gt;
**core_cmInstr.h&lt;br /&gt;
*Alle Dateien aus den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projektes&lt;br /&gt;
*Die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; aus dem &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner&lt;br /&gt;
&lt;br /&gt;
So sollte die Struktur dann aussehen:&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_7.png|Anwenungs-Grundgerüst]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Da einige Dateien der Libraries später bearbeitet werden müssen und Schreibgeschützt sind, weise ich hier schonmal darauf hin, das der Schreibschutz in der IDE über &#039;&#039;&#039;&#039;&#039;Rechts Klick auf die Datei -&amp;gt; Properties -&amp;gt; Häkchen bei &amp;quot;File is read only&amp;quot; entfernen&#039;&#039;&#039;&#039;&#039; entfert werden kann.&lt;br /&gt;
&lt;br /&gt;
Damit die IDE die Header-Dateien der CMSIS Library auch finden kann, weil diese ja nicht im standard Include Ordner &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; liegen, muss unter &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Build Options -&amp;gt; Search Directories&#039;&#039;&#039;&#039;&#039; der Pfad &#039;&#039;&#039;&#039;&#039;CMSIS\Include&#039;&#039;&#039;&#039;&#039; hinzugefügt werden.&lt;br /&gt;
&lt;br /&gt;
Compiliert man jetzt das Projekt mit &#039;&#039;&#039;&#039;&#039;F7&#039;&#039;&#039;&#039;&#039; gibt es ein paar Fehler Meldungen, weil keine Controller-Reihe ausgewählt wurde. Ebenfalls unter &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Build Options -&amp;gt; Compiler Settings -&amp;gt; #defines&#039;&#039;&#039;&#039;&#039; wird der Define &#039;&#039;&#039;&#039;&#039;STM32F40_41xxx&#039;&#039;&#039;&#039;&#039; hinzugefügt.&lt;br /&gt;
&lt;br /&gt;
Beim erneuten Compilieren sollten sich nun keine neuen Fehler ergeben.&lt;br /&gt;
&lt;br /&gt;
===Das erste Programm===&lt;br /&gt;
Nachdem ein grundsätzliches &amp;quot;Gerüst&amp;quot; fertig ist, kann man den ersten Code schreiben.&lt;br /&gt;
main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC-&amp;gt;AHB1ENR |= RCC_AHB1ENR_GPIODEN;    //Takt für GPIO aktivieren&lt;br /&gt;
    GPIOD-&amp;gt;MODER |= GPIO_MODER_MODER15_0;   //GPIOD Pin15 als Ausgang&lt;br /&gt;
    GPIOD-&amp;gt;BSRRL |= GPIO_BSRR_BS_15;        //GPIOD Pin15 auf High ziehen&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039; wird dann der Debugger gestartet. Hat der Debugger das Projekt erfolgreich übertragen kann die Ausführung mit &#039;&#039;&#039;&#039;&#039;F5&#039;&#039;&#039;&#039;&#039; begonnen werden.&lt;br /&gt;
&lt;br /&gt;
==Libraries einbinden/verwenden==&lt;br /&gt;
===Einbinden der Standard-Peripheral-Library===&lt;br /&gt;
Um nicht immer die einzelnen Register, wie im ersten &amp;quot;bare-metal&amp;quot; Beispiel, aus dem Reference-Manual zu suchen und zu beschreiben, gibt es von ST die Standard Peripheral Library, die diese Aufgaben übernimmt und mit der sich die &amp;quot;normale/grundlegende&amp;quot; (Alles außer USB und Ethernet) Peripherie recht einfach steuern lässt. Um die Library zu verwenden erzeugt man wie oben beschrieben ein neues Grundgerüst und kopiert als erstes den Ordner &#039;&#039;&#039;&#039;&#039;Libraries\STM32F4xx_StdPeriph_Driver&#039;&#039;&#039;&#039;&#039; aus dem Standard-Peripheral-Library Download in das Projekt-Verzeichnis. Außerdem muss man die Datei &#039;&#039;&#039;&#039;&#039;Project\STM32F4xx_StdPeriph_Templates\stm32f4xx_conf.h&#039;&#039;&#039;&#039;&#039; ebenfalls aus dem Standard-Peripheral-Library Download in den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projektes kopieren. In der IDE fügt man den Include-Path &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\inc&#039;&#039;&#039;&#039;&#039; hinzufügen, wie bei der CMSIS-Library (s.o.).&lt;br /&gt;
Außerdem muss noch &#039;&#039;&#039;&#039;&#039;USE_STDPERIPH_DRIVER&#039;&#039;&#039;&#039;&#039; als Define in der IDE hinzugefügt werden (s.o.).&lt;br /&gt;
Danach fügt man die Source- und Include-Dateien aus dem Ordner &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\inc&#039;&#039;&#039;&#039;&#039; und &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\src&#039;&#039;&#039;&#039;&#039; dem Project mit &#039;&#039;&#039;&#039;&#039;&amp;lt;Project Name&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Add files&#039;&#039;&#039;&#039;&#039; hinzu, allerdings nur die, für welche auch der Controller die entsprechende Peripherie besitzt. Beim STM32F4-Discovery Board / STM32F407VG Controller dürfen also nicht folgende Dateien nicht mit hinzugefügt werden, weil diese Peripherie nur bei anderen Controller vorhanden ist:&lt;br /&gt;
&lt;br /&gt;
*stm32f4xx_dma2d.c/.h&lt;br /&gt;
*stm32f4xx_fmc.c/.h&lt;br /&gt;
*stm32f4xx_ltdc.c/.h&lt;br /&gt;
*stm32f4xx_sai.c/.h&lt;br /&gt;
&lt;br /&gt;
Daraus resultiert folgende Struktur:&lt;br /&gt;
&lt;br /&gt;
[[Datei:stdperiphlib_2.png|Header-Struktur]] [[Datei:stdperiphlib_1.png|Source-Struktur]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Anschließen kann die Standard-Peripheral-Library benutz werden.&lt;br /&gt;
main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);&lt;br /&gt;
&lt;br /&gt;
    GPIO_InitTypeDef GPIOD_InitStructure;&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Mode = GPIO_Mode_OUT;     //Als Ausgang&lt;br /&gt;
    GPIOD_InitStructure.GPIO_OType = GPIO_OType_PP;    //Push-Pull Betrieb&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Pin = GPIO_Pin_15;        //Pin 15 (STM32F4-Discovery: Blaue LED)&lt;br /&gt;
    GPIOD_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;  //Kein Pull-Up oder Pull-Down Widerstand aktiviert&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Speed = GPIO_Speed_25MHz; //25MHz Update-Rate&lt;br /&gt;
    GPIO_Init(GPIOD, &amp;amp;GPIOD_InitStructure);&lt;br /&gt;
&lt;br /&gt;
    GPIO_SetBits(GPIOD, GPIO_Pin_15);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Einbinden der DSP-Library===&lt;br /&gt;
STM32F3 / STM32F4 Microcontroller haben neben der FPU noch einen Digital-Signal-Processor (DSP). Die DSP dient hauptsächlich dazu, viele Daten schnell zu verarbeiten (z.B. Video- oder Audiosignal). Der CMSIS-Download beinhaltet dazu neben der eigentlichen CMSIS-Library auch noch eine DSP-Library. Diese Library stellt sowohl einfache, mathematische Funktionen wie addieren, multiplizieren usw. als auch komplexe Funktionen, wie z.B  einen IIR-Filter, zur Verfügung. Die DSP-Library ist weiter aufgeteilt in kleinere Module, wie z.B. BasicMathFunctions, FilteringFunctions usw. (siehe &#039;&#039;&#039;&#039;&#039;CMSIS\DSP-Library\Source&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
Um die DSP-Library zu verwenden müssen eigentlich nur die Source-Files des benötigten Moduls einbinden.&lt;br /&gt;
(&#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Add files...&#039;&#039;&#039;&#039;&#039;). Außerdem muss in der &#039;&#039;&#039;&#039;&#039;main.c&#039;&#039;&#039;&#039;&#039; der Include &#039;&#039;&#039;&#039;&#039;arm_math.h&#039;&#039;&#039;&#039;&#039; eingebunden werden. Aus irgendeinem Grund gibt es dann jedoch die Warnung: &amp;quot;Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)&amp;quot;. Ich hab noch nicht rausgefunden, wieso diese Warnung auftaucht. Die Warnung verschwindet, wenn man in der &#039;&#039;&#039;&#039;&#039;Build options...&#039;&#039;&#039;&#039;&#039; das Define &#039;&#039;&#039;&#039;&#039;__FPU_PRESENT&#039;&#039;&#039;&#039;&#039; hinzufügt (Ich weiß selber das das keine schöne Lösung ist, eine andere hab ich jedoch noch nicht gefunden). Jetzt kann die DSP-Library verwedet werden. Das Beispiel multipliziert zwei Buffer miteinander. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
#include &amp;quot;arm_math.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    float32_t x[1024];&lt;br /&gt;
    float32_t y[1024];&lt;br /&gt;
    float32_t z[1024];&lt;br /&gt;
&lt;br /&gt;
    for(uint16_t i = 0; i &amp;lt; 1024; i++)&lt;br /&gt;
    {&lt;br /&gt;
        x[i] = i;&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for(uint16_t i = 0; i &amp;lt; 1024; i++)&lt;br /&gt;
    {&lt;br /&gt;
        y[i] = PI;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    arm_mult_f32(x, y, z, 1024);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Startup-Code, Linker-Script, Takt, FPU, Optimierung usw.==&lt;br /&gt;
===Startup-Code===&lt;br /&gt;
Em::Blocks fügt standardmäßig einen Startup-Code mit in das Projekt ein. Die wichtigsten Dinge die darin erledigt werden sind folgende:&lt;br /&gt;
&lt;br /&gt;
*Stack und Heap wird angelgt&lt;br /&gt;
*Die Vector-Table wird angelegt&lt;br /&gt;
*Ein Default Reset-Handler wird implementiert, dieser erledigt folgende aufgaben:&lt;br /&gt;
**Kopieren der definierten Daten aus dem Flash in den SRAM&lt;br /&gt;
**&#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; wird aufgerfen, wenn &#039;&#039;&#039;&#039;&#039;__NO_SYSTEM_INIT&#039;&#039;&#039;&#039;&#039; nicht definiert ist&lt;br /&gt;
**Sprung in die &#039;&#039;&#039;&#039;&#039;main()&#039;&#039;&#039;&#039;&#039; Funktion&lt;br /&gt;
*Allen anderen Interrupt-Handler wird eine Default-Funktion &#039;&#039;&#039;&#039;&#039;def_irq_handler&#039;&#039;&#039;&#039;&#039; mit einer &#039;&#039;&#039;&#039;&#039;while(1)&#039;&#039;&#039;&#039;&#039;-Schleife zugewiesen, falls kein anderer Interrupt-Handler existiert.&lt;br /&gt;
&lt;br /&gt;
Normalerweise muss am Startup-Code nichts verändert werden.&lt;br /&gt;
&lt;br /&gt;
===Linker-Script===&lt;br /&gt;
Em::Blocks stellt zwei fertige Linker-Scripts bereit, eins für die Ausführung des Programmes aus dem Flash (&#039;&#039;&#039;&#039;&#039;*_flash.ld&#039;&#039;&#039;&#039;&#039;), das andere für die Ausführung aus dem SRAM (&#039;&#039;&#039;&#039;&#039;*_sram.ld&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Normalerweise muss auch hier nichts geändert werden, es sei den Daten sollen in bestimmten Adressbereichen abgelegt werden (z.B. im Core-Coupled RAM), was ich später noch zum Tutorial hinzufüge.&lt;br /&gt;
&lt;br /&gt;
===Der Takt===&lt;br /&gt;
Jeder Controller oder Prozessor braucht einen Takt, indem er die einzelnen Maschinen-Befehle abarbeiten kann.&lt;br /&gt;
Bei den STM32 Mikrocontrollern kann dieser Takt aus verschiedenen Quellen kommen:&lt;br /&gt;
&lt;br /&gt;
1. High Speed Internal Oszillator (HSI)&lt;br /&gt;
&lt;br /&gt;
2. High Speed External Oszillator (HSE)&lt;br /&gt;
&lt;br /&gt;
3. Low Speed Internal Oszillator (LSI)&lt;br /&gt;
&lt;br /&gt;
4. Low Speed External Oszillator (LSE)&lt;br /&gt;
&lt;br /&gt;
5. Phase-Locked Loop (PLL) (generiert den Takt aus den ersten vier Taktquellen durch Teiler und Faktoren)&lt;br /&gt;
&lt;br /&gt;
Nach einem Reset wird der Controller aus der HSI Taktquelle versorgt (16MHz beim STM32F407VG). Um die voll Performance des Controllers zu erreichen muss die PLL verwendet werden, welche den Takt durch geschickte Teiler und Faktoren vervielfältigt, sodass am Ende der Controller mit der maximalen Taktfrequenz läuft. Die notwendige Initialisierung der PLL findet in der Funktion &#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; statt. Die PLL erzeugt zunächst einen Basistakt:&lt;br /&gt;
&lt;br /&gt;
PLL_VCO = (F_HSE / PLL_M) * PLL_N&lt;br /&gt;
&lt;br /&gt;
Aus diesem Takt wird dann der Takt für den Controller-Kern abgeleitet:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = PLL_VCO / PLL_P&lt;br /&gt;
&lt;br /&gt;
Und der Takt für SDIO / USB / RNG (48MHz):&lt;br /&gt;
&lt;br /&gt;
48MHz = PLL_VCO / PLL_Q&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Durch weiter Teiler werden, die Takte für die einzelnen Busse erzeugt, da diese nicht alle beliebig schnell betrieben werden dürfen.&lt;br /&gt;
&lt;br /&gt;
Genaue Angaben findet man zu dem jeweiligen Clock-System des Controllers im Reference Manual.&lt;br /&gt;
&lt;br /&gt;
Ein Blick in den &amp;quot;Kommentar-Header&amp;quot; verrät, dass von einem externen (HSE) Oszillator von 25MHz ausgegangen wird, der die PLL versorgen soll.&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((25MHz / PLL_M(25)) * PLL_N(336)) / PLL_P(2) = 168MHz&lt;br /&gt;
&lt;br /&gt;
Allerdings stimmt diese Rechnung natürlich nur, wenn wirklich ein 25MHz Quarz am Controller angeschlossen ist. Auf dem STM32F4-Discovery Board befindet sich aber nur ein 8MHz Quarz. Demnach gilt:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((8MHz / PLL_M(25)) * PLL_N(336)) / PLL_P(2) = 53.76MHz&lt;br /&gt;
&lt;br /&gt;
Der Controller läuft also nur mit 53.76MHz, wenn wie ober beschrieben ein Projekt erstellt wird. Allerdings kann dieses Problem durch ändern von den betroffen Defines behoben werden:&lt;br /&gt;
 &lt;br /&gt;
*Dazu geht man in die &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; Datei und passt zur Vollständigkeit erstmal die zum Controller passende Tabelle im &amp;quot;Kommentar-Header&amp;quot; an (Z.57f):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      HSE Frequency(Hz)                      | 8000000&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      PLL_M                                  | 8&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Danach passt man den PPL_M Define (Z.254) an:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/************************* PLL Parameters *************************************/&lt;br /&gt;
/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */&lt;br /&gt;
#define PLL_M      8&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Außerdem muss man den HSE_VALUE Define in der &#039;&#039;&#039;&#039;&#039;inc/stm32f4xx.h&#039;&#039;&#039;&#039;&#039; angepasst werden (Z.122):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#if !defined  (HSE_VALUE)&lt;br /&gt;
  #define HSE_VALUE    ((uint32_t)8000000) /*!&amp;lt; Value of the External oscillator in Hz */&lt;br /&gt;
&lt;br /&gt;
#endif /* HSE_VALUE */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine neue Berechnung zeigt:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((8MHz / PLL_M(8)) * PLL_N(336)) / PLL_P(2) = 168MHz&lt;br /&gt;
&lt;br /&gt;
Jetzt läuft der Controller mit maximaler Geschwindigkeit.&lt;br /&gt;
&lt;br /&gt;
Die Theorie wird durch folgendes Programm verifiziert. Der geviertelte System-Takt SYSCLK wir am Pin PC9 ausgegeben. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);&lt;br /&gt;
&lt;br /&gt;
    GPIO_InitTypeDef GPIOC_InitStructure;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Mode = GPIO_Mode_AF;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_OType = GPIO_OType_PP;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Pin = GPIO_Pin_9;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;&lt;br /&gt;
    GPIO_Init(GPIOC, &amp;amp;GPIOC_InitStructure);&lt;br /&gt;
&lt;br /&gt;
    RCC_MCO2Config(RCC_MCO2Source_SYSCLK, RCC_MCO2Div_4);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Die FPU===&lt;br /&gt;
====Allgemeines====&lt;br /&gt;
Damit die FPU richtig verwendet wird, müssen normalerweise zwei Bedingungen erfüllt sein:&lt;br /&gt;
&lt;br /&gt;
1. Der Controller muss in der Initialisierung-Funktion &#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; in &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; die FPU Hardware-seitig aktivieren&lt;br /&gt;
&lt;br /&gt;
2. Damit die FPU auch was zu tuen bekommt, müssen vom Compiler FPU-Instructions erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
Die Em::Blocks IDE verwendet standardmäßig die FPU, wenn eine Vorhanden ist. Hier wird die FPU Hardware-seitig aktiviert (&#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; Z.341):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* FPU settings ------------------------------------------------------------*/&lt;br /&gt;
  #if (__FPU_PRESENT == 1) &amp;amp;&amp;amp; (__FPU_USED == 1)&lt;br /&gt;
    SCB-&amp;gt;CPACR |= ((3UL &amp;lt;&amp;lt; 10*2)|(3UL &amp;lt;&amp;lt; 11*2));  /* set CP10 and CP11 Full Access */&lt;br /&gt;
  #endif&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
__FPU_PRESENT wird in der &#039;&#039;&#039;&#039;&#039;stm32f4xx.h&#039;&#039;&#039;&#039;&#039; definiert.&lt;br /&gt;
__FPU_USED wird von der IDE übernommen (siehe Build-Log): &#039;&#039;&#039;&#039;&#039;-D__FPU_USED&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Außerdem wird der Compiler von der IDE standardmäßig mit dem Argument &#039;&#039;&#039;&#039;&#039;-mfloat-abi=hard&#039;&#039;&#039;&#039;&#039; aufgerufen, wodurch FPU-Instructions erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
====FPU abschalten====&lt;br /&gt;
Um die FPU ab zu schalten (Mir würde jetzt nur Strom sparen als Grund einfallen) geht man wie folgt vor:&lt;br /&gt;
&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick Build options -&amp;gt; Device -&amp;gt; Policy&#039;&#039;&#039;&#039;&#039; wählt man &#039;&#039;&#039;&#039;&#039;Use target settings&#039;&#039;&#039;&#039;&#039; und über nimmt die Einstellungen, die vorher dort eingetragen waren, allerdings lässt man das Feld &#039;&#039;&#039;&#039;&#039;FP-hardware&#039;&#039;&#039;&#039;&#039; frei.&lt;br /&gt;
&lt;br /&gt;
[[Datei:fpu_1.png|FPU Abschalten Schritt 1]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;Compiler Settings -&amp;gt; Policy&#039;&#039;&#039;&#039;&#039; wählt man dann &#039;&#039;&#039;&#039;&#039;Use target options only&#039;&#039;&#039;&#039;&#039;. Dann kann man unter &#039;&#039;&#039;&#039;&#039;Categories&#039;&#039;&#039;&#039;&#039; die Option &#039;&#039;&#039;&#039;&#039;ARM FPU architecture&#039;&#039;&#039;&#039;&#039; auswählen. Dort stehen dann drei Möglichkeiten für die FPU zur Verfügung:&lt;br /&gt;
&lt;br /&gt;
1. Software-FPU-Library für Gleitkomma-Berechnung verwenden - Keine FPU-Instructions werden generiert (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=soft&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
2. Eine Mischung aus Software- und Hardware-FPU wird verwendet (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=softfp&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
3. Hardware-FPU wird für Gleitkomma-Berechnungen verwendet (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=hard&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
[[Datei:fpu_2.png|FPU Abschalten Schritt 2]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Um die FPU ab zu schalten wählt man natürlich die erste Möglichkeit.&lt;br /&gt;
Bei der 2. und 3. Möglichkeit fügt die IDE auch den Define &#039;&#039;&#039;&#039;&#039;__FPU_USED&#039;&#039;&#039;&#039;&#039; hinzu. Bei Der ersten Möglichkeit nicht. Der Code muss also nicht verändert / auskommentiert werden.&lt;br /&gt;
&lt;br /&gt;
Um die FPU wieder zu aktivieren müssen alle Schritte wieder rückgängig gemacht werden.&lt;br /&gt;
&lt;br /&gt;
Am besten ist es einfach mal alle Möglichkeiten im Einzelschritt durch zu probieren. Dann stellt man schnell fest, ob die FPU aktiviert wir oder nicht. Ein Blick in den erweiterten &#039;&#039;&#039;&#039;&#039;Build-Log&#039;&#039;&#039;&#039;&#039; gibt auch schnell Aufschluss darüber, wie der Compiler aufgerufen wird (siehe Kapitel [http://www.mikrocontroller.net/articles/STM32_-_Einstieg_mit_Em::Blocks#Compilieren Compilieren]).&lt;br /&gt;
&lt;br /&gt;
====Test Programm für die FPU====&lt;br /&gt;
Hier ein kleines Testprogramm, dass misst wie viele Taktzyklen für eine Gleitkomma-Multiplikation gebraucht werden. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define CORE_SysTickEn()    (*((u32*)0xE0001000)) = 0x40000001&lt;br /&gt;
#define CORE_SysTickDis()   (*((u32*)0xE0001000)) = 0x40000000&lt;br /&gt;
#define CORE_GetSysTick()   (*((u32*)0xE0001004))&lt;br /&gt;
&lt;br /&gt;
uint32_t t1, t2, dt;&lt;br /&gt;
float x, y, z;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    x = 53.64f;&lt;br /&gt;
    y = 0.27f;&lt;br /&gt;
&lt;br /&gt;
    CORE_SysTickEn();&lt;br /&gt;
    t1 = CORE_GetSysTick();&lt;br /&gt;
&lt;br /&gt;
    z = x * y;&lt;br /&gt;
&lt;br /&gt;
    t2 = CORE_GetSysTick();&lt;br /&gt;
    CORE_SysTickDis();&lt;br /&gt;
&lt;br /&gt;
    dt = (t2 - t1) - 9; //9 Takt-Zyklen werden für die Messung gebraucht &lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Compiler-Optimierung===&lt;br /&gt;
Standardmäßig verwendet Em::Blocks keine Optimierung. Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; Categories: Optimization&#039;&#039;&#039;&#039;&#039; kann zwischen verschieden Optimierungen ausgewählt werden.&lt;br /&gt;
&lt;br /&gt;
==Booten aus dem SRAM==&lt;br /&gt;
STM32 Controller haben die Möglichkeit Code aus dem Flash als auch aus dem SRAM auszuführen. Um eine Anwenung per Debugger in des SRAM zu laden sind nur wenige Schritte erforderlich:&lt;br /&gt;
&lt;br /&gt;
*Um das Linkerscript für den SRAM zu verwenden geht man zu: &#039;&#039;&#039;&#039;&#039;Build options... -&amp;gt; Device&#039;&#039;&#039;&#039;&#039; dort wählt man unter &#039;&#039;&#039;&#039;&#039;Policy&#039;&#039;&#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;Use target settings&#039;&#039;&#039;&#039;&#039; aus und übernimmt die vorherigen Einstellungen, nur unter &#039;&#039;&#039;&#039;&#039;Linker script*&#039;&#039;&#039;&#039;&#039; gibt man &#039;&#039;&#039;&#039;&#039;.\stm32f407vg_sram.ld&#039;&#039;&#039;&#039;&#039; an&lt;br /&gt;
&lt;br /&gt;
*Dann muss man noch unter &#039;&#039;&#039;&#039;&#039;Debug -&amp;gt; Interfaces -&amp;gt; Settings&#039;&#039;&#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;Vector table start&#039;&#039;&#039;&#039;&#039; auf 0x20000000 ändern und &#039;&#039;&#039;&#039;&#039;Execute from RAM&#039;&#039;&#039;&#039;&#039; auswählen.&lt;br /&gt;
&lt;br /&gt;
Anschließend kann man die Anwendung ganz normal debuggen. Nach einem Reset muss die Anwenung erneut mit dem Debugger gestartet werden.&lt;br /&gt;
&lt;br /&gt;
=Fortsetzung folgt..=&lt;br /&gt;
Kritik, Wünsche usw. sind gerne erwünscht, am besten hier in den Thread posten: [http://www.mikrocontroller.net/topic/323750 Neues STM32 Tutorial]&lt;br /&gt;
&lt;br /&gt;
[[Category:ARM]]&lt;br /&gt;
[[Category:STM32]]&lt;/div&gt;</summary>
		<author><name>Avrprogger</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=STM32_-_Einstieg_mit_Em::Blocks&amp;diff=81534</id>
		<title>STM32 - Einstieg mit Em::Blocks</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=STM32_-_Einstieg_mit_Em::Blocks&amp;diff=81534"/>
		<updated>2014-02-11T15:32:34Z</updated>

		<summary type="html">&lt;p&gt;Avrprogger: sdf&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In diesem Tutorial werde ich versuchen, möglichst einfach, die ersten Schritte zur Entwicklung von STM32 Anwenungen mit der Em::Blocks IDE zu erklären. Hier soll nicht so stark auf die einzelnen Peripherie-Module der Controller eingegangen werden, sondern mehr auf die IDE und die verschieden Libraries, wie die CMSIS Library, die DSP-Library, die Standard-Peripheral-Library, die USB-Library und vllt. über Ethernet. Ich denke ein Kapitel zu FreeRTOS wird es auch geben. Auserdem steht im Vordergrund Sachen wie z.B. booten aus dem SRAM, In-Application-Programming, FPU, Core-Coupled-RAM usw. Mal sehn wie weit ich komme ;)&lt;br /&gt;
&lt;br /&gt;
==Die Entwicklungsumgebung==&lt;br /&gt;
===Hardware===&lt;br /&gt;
Zum testen der Anwendungen, benutze ich das STM32F4-Discovery Board, welches einen Debugger, Peripherie und natürlich einen STM32 Controller (STM32F407VGT6) enthält. Deshalb sind alle Beispiele hier für den STM32F407VG Controller ausgelegt, können aber meisten 1:1 auf andere Controller portiert werden. Ich werde auch möglichsts keine STM32F4-Discovery Board spezifischen Libraries verwenden, damit der Portierungs-Vorgang möglichsts einfach bleibt.&lt;br /&gt;
&lt;br /&gt;
===Software===&lt;br /&gt;
In diesem Tutorial verwende ich [http://www.emblocks.org/ Em::Blocks] als IDE. Em::Blocks ist eine kostenlose, uneingeschränkte IDE, die alle STM32 Mikrcontroller unterstützt und sehr einfach zu bedienen ist.&lt;br /&gt;
nach dem Download kann die IDE per Dialog, sehr einfach, installiert werden. Als Compiler beinhaltet Em::Blocks den &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
Die IDE unterstützt zurzeit den ST-Link, den J-Link und es gibt eine Generic-Vorlage, durch welche andere Debugger konfiguriert werden können.&lt;br /&gt;
&lt;br /&gt;
Außerdem muss noch der passende Treiber für den Debugger installiert werden. Verwendet man ein Discovery-Board muss der [http://www.st.com/web/catalog/tools/FM146/CL1984/SC724/SS1677/PF251168 ST-Link/V2]-Treiber heruntergeladen und installiert werden. (Die Installation muss evtl. als Administrator ausgeführt werden, da sonst die Installation unvollständig wird.) Nach der Installation des Treibers kann man den Debugger über die entsprechende USB Schnittstelle an den PC anschließen und es sollte die Meldung von Windows kommen, dass der richtige Treiber gefunden wurde.&lt;br /&gt;
&lt;br /&gt;
===Libraries===&lt;br /&gt;
Zum programmieren benötigt man noch die [http://www.arm.com/products/processors/cortex-m/cortex-microcontroller-software-interface-standard.php CMSIS] und die Standard-Peripheral-Library (z.B. für die F4 Controller [http://www.st.com/stonline/stappl/productcatalog/app?page=partNumberSearchPage&amp;amp;levelid=SS1577&amp;amp;parentid=1743&amp;amp;resourcetype=SW Standard-Peripheral-Library-F4]), die man am besten in einen Ordner (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\STM32&#039;&#039;&#039;&#039;&#039;) entpackt&lt;br /&gt;
&lt;br /&gt;
==Basis-Wissen zur IDE==&lt;br /&gt;
Einige Grundfunktionalitäten der IDE:&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von Dateien zum Projekt===&lt;br /&gt;
Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf &amp;lt;ProjektName&amp;gt; -&amp;gt; Add files...&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Enfernen von Dateien aus dem Projekt===&lt;br /&gt;
Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf die Datei / mehrere Dateien auswählen -&amp;gt; Remove file from project&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
Die Dateien werden lediglich aus dem Projekt entfernt und nicht von der Festplatte gelöscht.&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von Include-Pfaden===&lt;br /&gt;
Sofern die Include-Datei(en) nicht im standard Include-Ordner &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; des Projektes liegen, muss man den Pfad zum Projekt hinzufügen, damit der Compiler die Include-Dateien später auch finden kann. Man geht wie folgt vor: Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf &amp;lt;ProjektName&amp;gt; -&amp;gt; Build options... -&amp;gt; Search Directories -&amp;gt; Add&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Compilieren===&lt;br /&gt;
Entweder über das &#039;&#039;&#039;&#039;&#039;Build&#039;&#039;&#039;&#039;&#039; Menü oder über &#039;&#039;&#039;&#039;&#039;F7&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Um eine genau Ausgabe des Compiler-Aufrufes mit allen Argumenten zu bekommen, geht man im &#039;&#039;&#039;&#039;&#039;Settings&#039;&#039;&#039;&#039;&#039; Menü auf &#039;&#039;&#039;&#039;&#039;Tools...&#039;&#039;&#039;&#039;&#039; und dann auf &#039;&#039;&#039;&#039;&#039;Toolchain executables&#039;&#039;&#039;&#039;&#039;. Ganz unten, unter &#039;&#039;&#039;&#039;&#039;Logging&#039;&#039;&#039;&#039;&#039; kann man dann &#039;&#039;&#039;&#039;&#039;Full command line&#039;&#039;&#039;&#039;&#039; auswählen.&lt;br /&gt;
&lt;br /&gt;
===Debuggen===&lt;br /&gt;
*Als erstes den Debugger starten über das &#039;&#039;&#039;&#039;&#039;Debug&#039;&#039;&#039;&#039;&#039; Menü und &#039;&#039;&#039;&#039;&#039;Start/stop Debug Session&#039;&#039;&#039;&#039;&#039; oder über &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
*Danach läuft die Anwendung auf dem Controller und warten im &#039;&#039;&#039;&#039;&#039;Reset_Handler&#039;&#039;&#039;&#039;&#039; auf Einzelschritt- bzw. Run- Befehle (&#039;&#039;&#039;&#039;&#039;F5, F10, F11&#039;&#039;&#039;&#039;&#039; usw..(siehe &#039;&#039;&#039;&#039;&#039;Debug-Menü&#039;&#039;&#039;&#039;&#039; für alle Möglichkeiten))&lt;br /&gt;
&lt;br /&gt;
*Mit &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039; wird die Debug-Session auch wieder beendet&lt;br /&gt;
&lt;br /&gt;
*Unter &#039;&#039;&#039;&#039;&#039;Debug -&amp;gt; Interfaces -&amp;gt; Target settings&#039;&#039;&#039;&#039;&#039; können Eigenschaften, wie z.B &#039;&#039;&#039;&#039;&#039;Run to main()&#039;&#039;&#039;&#039;&#039; aktiviert werden.&lt;br /&gt;
&lt;br /&gt;
===Projekt als Template abspeichern===&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;File -&amp;gt; Save project as template...&#039;&#039;&#039;&#039;&#039;. Das Template erscheint dann im Projekt-Dialog unter &#039;&#039;&#039;&#039;&#039;User templates&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Das erste Projekt erstellen==&lt;br /&gt;
Hier erkläre ich, wie man am Besten (aus meiner Sicht), ein neues Projekt von Grund auf erstellt, sodass man hinterher, den Controller-Kern über die CMSIS-Library und die Peripherie über die Register steuern kann.&lt;br /&gt;
&lt;br /&gt;
===1. Projekt mit der IDE erstellen===&lt;br /&gt;
Nach der Installation der oben beschriebenen Komponenten erstellt man am besten ein Verzeichnis (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\EmBlocks&#039;&#039;&#039;&#039;&#039;), indem später alle Projekte gespeichert werden. Für Libraries kann man auch noch ein Verzeichnis (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\STM32&#039;&#039;&#039;&#039;&#039;) erstellen, wo alle Libraries gespeichert werden, die man für die Projekt brauchen.&lt;br /&gt;
&lt;br /&gt;
Als nächstes starten man EmBlocks. Bei dem ersten Start öffnet sich ein Fenster, wo verschiedene Compiler angezeigt werden, die Em::Blocks findet. Dort wählt man den &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039; aus und klickt &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039;. Nun sollte sich das Hauptfenster von Em::Blocks öffnen. Über &#039;&#039;&#039;&#039;&#039;Create a new Project&#039;&#039;&#039;&#039;&#039; oder &#039;&#039;&#039;&#039;&#039;File -&amp;gt; New -&amp;gt; Project&#039;&#039;&#039;&#039;&#039; ruft man den Projekt-Dialog auf und kann ein neues Projekt erzeugen.&lt;br /&gt;
&lt;br /&gt;
Auf der Ersten Seite wählen man den &#039;&#039;&#039;&#039;&#039;STmicro-ARM&#039;&#039;&#039;&#039;&#039; Projekt-Typ aus.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_1.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auf der nächsten Seite wird man darauf hingewiesen, dass das der entsprechende Projekt-Typ-Dialog ausgeführt wird. Hier kann man ein Häkchen bei &#039;&#039;&#039;&#039;&#039;Skip this page next time&#039;&#039;&#039;&#039;&#039; setzen und auf &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; klicken.&lt;br /&gt;
&lt;br /&gt;
Im nächsten Schritt wählen man das zuvor erstellt Verzeichnis unter &#039;&#039;&#039;&#039;&#039;Folder to create Project in&#039;&#039;&#039;&#039;&#039; aus, indem später alle Projekt gespeichert werden. Außerdem geben wir dem Projekt einen Namen (z.B. &#039;&#039;&#039;&#039;&#039;FirstProject&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_2.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danach muss man einen Compiler auswählen und bestimmen, welche Projekt-Konfigurationen erszeugt werden sollen. Unter &#039;&#039;&#039;&#039;&#039;Compiler&#039;&#039;&#039;&#039;&#039; wählt man &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039; und man kann das Häkchen bei &#039;&#039;&#039;&#039;&#039;Create &amp;quot;Release&amp;quot; configuration&#039;&#039;&#039;&#039;&#039; entfernen, da diese unnötig ist, die Debug-Konfiguration sollte eig. immer ausreichen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_3.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auf den folgenden Seite wird der Controller ausgewählt. Verwendet man ein STM32F4-Discovery Board müssen folgende Dinge gewählt werden: &#039;&#039;&#039;&#039;&#039;Cortex_M4 (F3xx - F4xx) -&amp;gt; STM32F4xx (Cortex M4 with FPU) -&amp;gt; STM32F407VG&#039;&#039;&#039;&#039;&#039;. Leider sind die Auswahl Möglichkeiten nicht ganz richtig, da auch die F3 Controller einen Cortex M4 Kern und eine FPU haben (Ist aber nicht so wichtig, ist nur eine formale Sache). Außerdem entfernt man das Häkchen bei &#039;&#039;&#039;&#039;&#039;Standard Peripherals Library&#039;&#039;&#039;&#039;&#039; (Wie man die Standard-Peripheral-Library einbindet und verwendet erkläre ich später). Man kann auch das Häkchen bei &#039;&#039;&#039;&#039;&#039;Create hex file for Realease target&#039;&#039;&#039;&#039;&#039; entfernen.&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;Stack Size&#039;&#039;&#039;&#039;&#039; und &#039;&#039;&#039;&#039;&#039;Heap Size&#039;&#039;&#039;&#039;&#039; wird die Größe von Stack und Heap festgelegt. Für eine erste Anwendung kann man die Einstellungen so lassen (Stack-Size: 0x0100 =&amp;gt; 256 Byte Stack und Heap-Size: 0x0000 =&amp;gt; kein Heap). Mit &#039;&#039;&#039;&#039;&#039;Finish&#039;&#039;&#039;&#039;&#039; ist der Projekt Dialog abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_4.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danach sollten sich zwei neue Fenster öffnen, um die Debug-Eigenschaften fest zu legen.&lt;br /&gt;
Verwendet man ein Discovery Board/ST-Link müssen die Einstellungen wie auf dem Bild gewählt werden. Über den Button &#039;&#039;&#039;&#039;&#039;Settings&#039;&#039;&#039;&#039;&#039; öffnet sich das zweite Fenster, falls sich dieses nicht schon von alleine öffnen sollte. Nach den Schließen der Fenster über &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; ist der Projekt Dialog beendet und ein neues Projekt steht zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_5_1.png|Debug Eigenschaften 1. Fenster]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_5_2.png|Debug Eigenschaften 2. Fenster]]&lt;br /&gt;
&lt;br /&gt;
===2. CMSIS-Library und Startup-Code hinzufügen===&lt;br /&gt;
Wenn man sich, nachdem man ein neues Projekt in der IDE erstellt hat, die bereits vorhandenen Dateien im Projekt ansieht, stellt man fest, das bereits ein Ordner &#039;&#039;&#039;&#039;&#039;cmsis&#039;&#039;&#039;&#039;&#039; existiert, der einige wichtige Include-Dateien der CMSIS-Library enthält. Allerdings sind das wirklich nur die wichtigsten Include-Dateien der CMSIS-Library und dazu noch, die aus einer älternen Version. Ich ziehe es deshalb vor die &amp;quot;Mini-CMSIS-Libraray&amp;quot; und die &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c/.h&#039;&#039;&#039;&#039;&#039; Dateien des Projektes durch aktuellere Versionen zu ersetzen. So ist später auch die Integration  von anderen Libraries, wie z.B. der CMSIS-DSP-Libarary einfacher.  &lt;br /&gt;
&lt;br /&gt;
Zunächst gehen man in das Projekt-Verzeichnis und löscht:&lt;br /&gt;
*Den Ordner &#039;&#039;&#039;&#039;&#039;cmsis&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Alle Dateien im Include Verzeichnis &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; im &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner&lt;br /&gt;
&lt;br /&gt;
Außerdem entfernt man auch alle gelöschten Dateien in der IDE aus dem Projekt mit &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Rechts Klick -&amp;gt; Remove file from project&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Es sollte folgende Verzeichnis Struktur überbleiben:&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_6.png|Überbleibende Dateien]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Jetzt müssen die gelöschten Dateien durch die aktuelleren ersetzt werden.&lt;br /&gt;
&lt;br /&gt;
*Dazu kopieren man den gesamten Ordner &#039;&#039;&#039;&#039;&#039;CMSIS&#039;&#039;&#039;&#039;&#039; aus dem CMSIS Download in das Projekt Verzeichnis.&lt;br /&gt;
&lt;br /&gt;
*Aus dem Standard-Peripheral-Library Download kopiert man von &#039;&#039;&#039;&#039;&#039;Libraries\CMSIS\Device\ST\STM32F4xx\Include&#039;&#039;&#039;&#039;&#039; alle Dateien in den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projekt Verzeichnisses&lt;br /&gt;
&lt;br /&gt;
*Aus der Standard-Peripheral-Library kopieren man ebenfalls von &#039;&#039;&#039;&#039;&#039;Libraries\CMSIS\Device\ST\STM32F4xx\Source\Templates&#039;&#039;&#039;&#039;&#039; die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; in den &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner des Projekts&lt;br /&gt;
&lt;br /&gt;
Anschließend müssen die neuen Dateien in der IDE dem Projekt hinzugefügt werden. Dazu benutzt man &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Rechts Klick -&amp;gt; Add files&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
*Aus dem &#039;&#039;&#039;&#039;&#039;CMSIS&#039;&#039;&#039;&#039;&#039; Ordner im Projekt Verzeichnis werden aus den Unterorder &#039;&#039;&#039;&#039;&#039;Include&#039;&#039;&#039;&#039;&#039; folgende Dateien dem Projekt hinzugefügt:&lt;br /&gt;
**arm_common_tables.h&lt;br /&gt;
**arm_const_structs.h&lt;br /&gt;
**arm_math.h&lt;br /&gt;
**core_cm4.h&lt;br /&gt;
**core_cm4_simd.h&lt;br /&gt;
**core_cmFunc.h&lt;br /&gt;
**core_cmInstr.h&lt;br /&gt;
*Alle Dateien aus den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projektes&lt;br /&gt;
*Die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; aus dem &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner&lt;br /&gt;
&lt;br /&gt;
So sollte die Struktur dann aussehen:&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_7.png|Anwenungs-Grundgerüst]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Da einige Dateien der Libraries später bearbeitet werden müssen und Schreibgeschützt sind, weise ich hier schonmal darauf hin, das der Schreibschutz in der IDE über &#039;&#039;&#039;&#039;&#039;Rechts Klick auf die Datei -&amp;gt; Properties -&amp;gt; Häkchen bei &amp;quot;File is read only&amp;quot; entfernen&#039;&#039;&#039;&#039;&#039; entfert werden kann.&lt;br /&gt;
&lt;br /&gt;
Damit die IDE die Header-Dateien der CMSIS Library auch finden kann, weil diese ja nicht im standard Include Ordner &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; liegen, muss unter &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Build Options -&amp;gt; Search Directories&#039;&#039;&#039;&#039;&#039; der Pfad &#039;&#039;&#039;&#039;&#039;CMSIS\Include&#039;&#039;&#039;&#039;&#039; hinzugefügt werden.&lt;br /&gt;
&lt;br /&gt;
Compiliert man jetzt das Projekt mit &#039;&#039;&#039;&#039;&#039;F7&#039;&#039;&#039;&#039;&#039; gibt es ein paar Fehler Meldungen, weil keine Controller-Reihe ausgewählt wurde. Ebenfalls unter &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Build Options -&amp;gt; Compiler Settings -&amp;gt; #defines&#039;&#039;&#039;&#039;&#039; wird der Define &#039;&#039;&#039;&#039;&#039;STM32F40_41xxx&#039;&#039;&#039;&#039;&#039; hinzugefügt.&lt;br /&gt;
&lt;br /&gt;
Beim erneuten Compilieren sollten sich nun keine neuen Fehler ergeben.&lt;br /&gt;
&lt;br /&gt;
===Das erste Programm===&lt;br /&gt;
Nachdem ein grundsätzliches &amp;quot;Gerüst&amp;quot; fertig ist, kann man den ersten Code schreiben.&lt;br /&gt;
main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC-&amp;gt;AHB1ENR |= RCC_AHB1ENR_GPIODEN;    //Takt für GPIO aktivieren&lt;br /&gt;
    GPIOD-&amp;gt;MODER |= GPIO_MODER_MODER15_0;   //GPIOD Pin15 als Ausgang&lt;br /&gt;
    GPIOD-&amp;gt;BSRRL |= GPIO_BSRR_BS_15;        //GPIOD Pin15 auf High ziehen&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039; wird dann der Debugger gestartet. Hat der Debugger das Projekt erfolgreich übertragen kann die Ausführung mit &#039;&#039;&#039;&#039;&#039;F5&#039;&#039;&#039;&#039;&#039; begonnen werden.&lt;br /&gt;
&lt;br /&gt;
==Libraries einbinden/verwenden==&lt;br /&gt;
===Einbinden der Standard-Peripheral-Library===&lt;br /&gt;
Um nicht immer die einzelnen Register, wie im ersten &amp;quot;bare-metal&amp;quot; Beispiel, aus dem Reference-Manual zu suchen und zu beschreiben, gibt es von ST die Standard Peripheral Library, die diese Aufgaben übernimmt und mit der sich die &amp;quot;normale/grundlegende&amp;quot; (Alles außer USB und Ethernet) Peripherie recht einfach steuern lässt. Um die Library zu verwenden erzeugt man wie oben beschrieben ein neues Grundgerüst und kopiert als erstes den Ordner &#039;&#039;&#039;&#039;&#039;Libraries\STM32F4xx_StdPeriph_Driver&#039;&#039;&#039;&#039;&#039; aus dem Standard-Peripheral-Library Download in das Projekt-Verzeichnis. Außerdem muss man die Datei &#039;&#039;&#039;&#039;&#039;Project\STM32F4xx_StdPeriph_Templates\stm32f4xx_conf.h&#039;&#039;&#039;&#039;&#039; ebenfalls aus dem Standard-Peripheral-Library Download in den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projektes kopieren. In der IDE fügt man den Include-Path &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\inc&#039;&#039;&#039;&#039;&#039; hinzufügen, wie bei der CMSIS-Library (s.o.).&lt;br /&gt;
Außerdem muss noch &#039;&#039;&#039;&#039;&#039;USE_STDPERIPH_DRIVER&#039;&#039;&#039;&#039;&#039; als Define in der IDE hinzugefügt werden (s.o.).&lt;br /&gt;
Danach fügt man die Source- und Include-Dateien aus dem Ordner &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\inc&#039;&#039;&#039;&#039;&#039; und &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\src&#039;&#039;&#039;&#039;&#039; dem Project mit &#039;&#039;&#039;&#039;&#039;&amp;lt;Project Name&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Add files&#039;&#039;&#039;&#039;&#039; hinzu, allerdings nur die, für welche auch der Controller die entsprechende Peripherie besitzt. Beim STM32F4-Discovery Board / STM32F407VG Controller dürfen also nicht folgende Dateien nicht mit hinzugefügt werden, weil diese Peripherie nur bei anderen Controller vorhanden ist:&lt;br /&gt;
&lt;br /&gt;
*stm32f4xx_dma2d.c/.h&lt;br /&gt;
*stm32f4xx_fmc.c/.h&lt;br /&gt;
*stm32f4xx_ltdc.c/.h&lt;br /&gt;
*stm32f4xx_sai.c/.h&lt;br /&gt;
&lt;br /&gt;
Daraus resultiert folgende Struktur:&lt;br /&gt;
&lt;br /&gt;
[[Datei:stdperiphlib_2.png|Header-Struktur]] [[Datei:stdperiphlib_1.png|Source-Struktur]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Anschließen kann die Standard-Peripheral-Library benutz werden.&lt;br /&gt;
main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);&lt;br /&gt;
&lt;br /&gt;
    GPIO_InitTypeDef GPIOD_InitStructure;&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Mode = GPIO_Mode_OUT;     //Als Ausgang&lt;br /&gt;
    GPIOD_InitStructure.GPIO_OType = GPIO_OType_PP;    //Push-Pull Betrieb&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Pin = GPIO_Pin_15;        //Pin 15 (STM32F4-Discovery: Blaue LED)&lt;br /&gt;
    GPIOD_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;  //Kein Pull-Up oder Pull-Down Widerstand aktiviert&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Speed = GPIO_Speed_25MHz; //25MHz Update-Rate&lt;br /&gt;
    GPIO_Init(GPIOD, &amp;amp;GPIOD_InitStructure);&lt;br /&gt;
&lt;br /&gt;
    GPIO_SetBits(GPIOD, GPIO_Pin_15);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Einbinden der DSP-Library===&lt;br /&gt;
&lt;br /&gt;
==Startup-Code, Linker-Script, Takt, FPU, Optimierung usw.==&lt;br /&gt;
===Startup-Code===&lt;br /&gt;
Em::Blocks fügt standardmäßig einen Startup-Code mit in das Projekt ein. Die wichtigsten Dinge die darin erledigt werden sind folgende:&lt;br /&gt;
&lt;br /&gt;
*Stack und Heap wird angelgt&lt;br /&gt;
*Die Vector-Table wird angelegt&lt;br /&gt;
*Ein Default Reset-Handler wird implementiert, dieser erledigt folgende aufgaben:&lt;br /&gt;
**Kopieren der definierten Daten aus dem Flash in den SRAM&lt;br /&gt;
**&#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; wird aufgerfen, wenn &#039;&#039;&#039;&#039;&#039;__NO_SYSTEM_INIT&#039;&#039;&#039;&#039;&#039; nicht definiert ist&lt;br /&gt;
**Sprung in die &#039;&#039;&#039;&#039;&#039;main()&#039;&#039;&#039;&#039;&#039; Funktion&lt;br /&gt;
*Allen anderen Interrupt-Handler wird eine Default-Funktion &#039;&#039;&#039;&#039;&#039;def_irq_handler&#039;&#039;&#039;&#039;&#039; mit einer &#039;&#039;&#039;&#039;&#039;while(1)&#039;&#039;&#039;&#039;&#039;-Schleife zugewiesen, falls kein anderer Interrupt-Handler existiert.&lt;br /&gt;
&lt;br /&gt;
Normalerweise muss am Startup-Code nichts verändert werden.&lt;br /&gt;
&lt;br /&gt;
===Linker-Script===&lt;br /&gt;
Em::Blocks stellt zwei fertige Linker-Scripts bereit, eins für die Ausführung des Programmes aus dem Flash (&#039;&#039;&#039;&#039;&#039;*_flash.ld&#039;&#039;&#039;&#039;&#039;), das andere für die Ausführung aus dem SRAM (&#039;&#039;&#039;&#039;&#039;*_sram.ld&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Normalerweise muss auch hier nichts geändert werden, es sei den Daten sollen in bestimmten Adressbereichen abgelegt werden (z.B. im Core-Coupled RAM), was ich später noch zum Tutorial hinzufüge.&lt;br /&gt;
&lt;br /&gt;
===Der Takt===&lt;br /&gt;
Jeder Controller oder Prozessor braucht einen Takt, indem er die einzelnen Maschinen-Befehle abarbeiten kann.&lt;br /&gt;
Bei den STM32 Mikrocontrollern kann dieser Takt aus verschiedenen Quellen kommen:&lt;br /&gt;
&lt;br /&gt;
1. High Speed Internal Oszillator (HSI)&lt;br /&gt;
&lt;br /&gt;
2. High Speed External Oszillator (HSE)&lt;br /&gt;
&lt;br /&gt;
3. Low Speed Internal Oszillator (LSI)&lt;br /&gt;
&lt;br /&gt;
4. Low Speed External Oszillator (LSE)&lt;br /&gt;
&lt;br /&gt;
5. Phase-Locked Loop (PLL) (generiert den Takt aus den ersten vier Taktquellen durch Teiler und Faktoren)&lt;br /&gt;
&lt;br /&gt;
Nach einem Reset wird der Controller aus der HSI Taktquelle versorgt (16MHz beim STM32F407VG). Um die voll Performance des Controllers zu erreichen muss die PLL verwendet werden, welche den Takt durch geschickte Teiler und Faktoren vervielfältigt, sodass am Ende der Controller mit der maximalen Taktfrequenz läuft. Die notwendige Initialisierung der PLL findet in der Funktion &#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; statt. Die PLL erzeugt zunächst einen Basistakt:&lt;br /&gt;
&lt;br /&gt;
PLL_VCO = (F_HSE / PLL_M) * PLL_N&lt;br /&gt;
&lt;br /&gt;
Aus diesem Takt wird dann der Takt für den Controller-Kern abgeleitet:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = PLL_VCO / PLL_P&lt;br /&gt;
&lt;br /&gt;
Und der Takt für SDIO / USB / RNG (48MHz):&lt;br /&gt;
&lt;br /&gt;
48MHz = PLL_VCO / PLL_Q&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Durch weiter Teiler werden, die Takte für die einzelnen Busse erzeugt, da diese nicht alle beliebig schnell betrieben werden dürfen.&lt;br /&gt;
&lt;br /&gt;
Genaue Angaben findet man zu dem jeweiligen Clock-System des Controllers im Reference Manual.&lt;br /&gt;
&lt;br /&gt;
Ein Blick in den &amp;quot;Kommentar-Header&amp;quot; verrät, dass von einem externen (HSE) Oszillator von 25MHz ausgegangen wird, der die PLL versorgen soll.&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((25MHz / PLL_M(25)) * PLL_N(336)) / PLL_P(2) = 168MHz&lt;br /&gt;
&lt;br /&gt;
Allerdings stimmt diese Rechnung natürlich nur, wenn wirklich ein 25MHz Quarz am Controller angeschlossen ist. Auf dem STM32F4-Discovery Board befindet sich aber nur ein 8MHz Quarz. Demnach gilt:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((8MHz / PLL_M(25)) * PLL_N(336)) / PLL_P(2) = 53.76MHz&lt;br /&gt;
&lt;br /&gt;
Der Controller läuft also nur mit 53.76MHz, wenn wie ober beschrieben ein Projekt erstellt wird. Allerdings kann dieses Problem durch ändern von den betroffen Defines behoben werden:&lt;br /&gt;
 &lt;br /&gt;
*Dazu geht man in die &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; Datei und passt zur Vollständigkeit erstmal die zum Controller passende Tabelle im &amp;quot;Kommentar-Header&amp;quot; an (Z.57f):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      HSE Frequency(Hz)                      | 8000000&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      PLL_M                                  | 8&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Danach passt man den PPL_M Define (Z.254) an:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/************************* PLL Parameters *************************************/&lt;br /&gt;
/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */&lt;br /&gt;
#define PLL_M      8&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Außerdem muss man den HSE_VALUE Define in der &#039;&#039;&#039;&#039;&#039;inc/stm32f4xx.h&#039;&#039;&#039;&#039;&#039; angepasst werden (Z.122):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#if !defined  (HSE_VALUE)&lt;br /&gt;
  #define HSE_VALUE    ((uint32_t)8000000) /*!&amp;lt; Value of the External oscillator in Hz */&lt;br /&gt;
&lt;br /&gt;
#endif /* HSE_VALUE */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine neue Berechnung zeigt:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((8MHz / PLL_M(8)) * PLL_N(336)) / PLL_P(2) = 168MHz&lt;br /&gt;
&lt;br /&gt;
Jetzt läuft der Controller mit maximaler Geschwindigkeit.&lt;br /&gt;
&lt;br /&gt;
Die Theorie wird durch folgendes Programm verifiziert. Der geviertelte System-Takt SYSCLK wir am Pin PC9 ausgegeben. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);&lt;br /&gt;
&lt;br /&gt;
    GPIO_InitTypeDef GPIOC_InitStructure;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Mode = GPIO_Mode_AF;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_OType = GPIO_OType_PP;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Pin = GPIO_Pin_9;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;&lt;br /&gt;
    GPIO_Init(GPIOC, &amp;amp;GPIOC_InitStructure);&lt;br /&gt;
&lt;br /&gt;
    RCC_MCO2Config(RCC_MCO2Source_SYSCLK, RCC_MCO2Div_4);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Die FPU===&lt;br /&gt;
====Allgemeines====&lt;br /&gt;
Damit die FPU richtig verwendet wird, müssen normalerweise zwei Bedingungen erfüllt sein:&lt;br /&gt;
&lt;br /&gt;
1. Der Controller muss in der Initialisierung-Funktion &#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; in &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; die FPU Hardware-seitig aktivieren&lt;br /&gt;
&lt;br /&gt;
2. Damit die FPU auch was zu tuen bekommt, müssen vom Compiler FPU-Instructions erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
Die Em::Blocks IDE verwendet standardmäßig die FPU, wenn eine Vorhanden ist. Hier wird die FPU Hardware-seitig aktiviert (&#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; Z.341):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* FPU settings ------------------------------------------------------------*/&lt;br /&gt;
  #if (__FPU_PRESENT == 1) &amp;amp;&amp;amp; (__FPU_USED == 1)&lt;br /&gt;
    SCB-&amp;gt;CPACR |= ((3UL &amp;lt;&amp;lt; 10*2)|(3UL &amp;lt;&amp;lt; 11*2));  /* set CP10 and CP11 Full Access */&lt;br /&gt;
  #endif&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
__FPU_PRESENT wird in der &#039;&#039;&#039;&#039;&#039;stm32f4xx.h&#039;&#039;&#039;&#039;&#039; definiert.&lt;br /&gt;
__FPU_USED wird von der IDE übernommen (siehe Build-Log): &#039;&#039;&#039;&#039;&#039;-D__FPU_USED&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Außerdem wird der Compiler von der IDE standardmäßig mit dem Argument &#039;&#039;&#039;&#039;&#039;-mfloat-abi=hard&#039;&#039;&#039;&#039;&#039; aufgerufen, wodurch FPU-Instructions erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
====FPU abschalten====&lt;br /&gt;
Um die FPU ab zu schalten (Mir würde jetzt nur Strom sparen als Grund einfallen) geht man wie folgt vor:&lt;br /&gt;
&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick Build options -&amp;gt; Device -&amp;gt; Policy&#039;&#039;&#039;&#039;&#039; wählt man &#039;&#039;&#039;&#039;&#039;Use target settings&#039;&#039;&#039;&#039;&#039; und über nimmt die Einstellungen, die vorher dort eingetragen waren, allerdings lässt man das Feld &#039;&#039;&#039;&#039;&#039;FP-hardware&#039;&#039;&#039;&#039;&#039; frei.&lt;br /&gt;
&lt;br /&gt;
[[Datei:fpu_1.png|FPU Abschalten Schritt 1]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;Compiler Settings -&amp;gt; Policy&#039;&#039;&#039;&#039;&#039; wählt man dann &#039;&#039;&#039;&#039;&#039;Use target options only&#039;&#039;&#039;&#039;&#039;. Dann kann man unter &#039;&#039;&#039;&#039;&#039;Categories&#039;&#039;&#039;&#039;&#039; die Option &#039;&#039;&#039;&#039;&#039;ARM FPU architecture&#039;&#039;&#039;&#039;&#039; auswählen. Dort stehen dann drei Möglichkeiten für die FPU zur Verfügung:&lt;br /&gt;
&lt;br /&gt;
1. Software-FPU-Library für Gleitkomma-Berechnung verwenden - Keine FPU-Instructions werden generiert (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=soft&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
2. Eine Mischung aus Software- und Hardware-FPU wird verwendet (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=softfp&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
3. Hardware-FPU wird für Gleitkomma-Berechnungen verwendet (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=hard&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
[[Datei:fpu_2.png|FPU Abschalten Schritt 2]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Um die FPU ab zu schalten wählt man natürlich die erste Möglichkeit.&lt;br /&gt;
Bei der 2. und 3. Möglichkeit fügt die IDE auch den Define &#039;&#039;&#039;&#039;&#039;__FPU_USED&#039;&#039;&#039;&#039;&#039; hinzu. Bei Der ersten Möglichkeit nicht. Der Code muss also nicht verändert / auskommentiert werden.&lt;br /&gt;
&lt;br /&gt;
Um die FPU wieder zu aktivieren müssen alle Schritte wieder rückgängig gemacht werden.&lt;br /&gt;
&lt;br /&gt;
Am besten ist es einfach mal alle Möglichkeiten im Einzelschritt durch zu probieren. Dann stellt man schnell fest, ob die FPU aktiviert wir oder nicht. Ein Blick in den erweiterten &#039;&#039;&#039;&#039;&#039;Build-Log&#039;&#039;&#039;&#039;&#039; gibt auch schnell Aufschluss darüber, wie der Compiler aufgerufen wird (siehe Kapitel [http://www.mikrocontroller.net/articles/STM32_-_Einstieg_mit_Em::Blocks#Compilieren Compilieren]).&lt;br /&gt;
&lt;br /&gt;
====Test Programm für die FPU====&lt;br /&gt;
Hier ein kleines Testprogramm, dass misst wie viele Taktzyklen für eine Gleitkomma-Multiplikation gebraucht werden. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define CORE_SysTickEn()    (*((u32*)0xE0001000)) = 0x40000001&lt;br /&gt;
#define CORE_SysTickDis()   (*((u32*)0xE0001000)) = 0x40000000&lt;br /&gt;
#define CORE_GetSysTick()   (*((u32*)0xE0001004))&lt;br /&gt;
&lt;br /&gt;
uint32_t t1, t2, dt;&lt;br /&gt;
float x, y, z;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    x = 53.64f;&lt;br /&gt;
    y = 0.27f;&lt;br /&gt;
&lt;br /&gt;
    CORE_SysTickEn();&lt;br /&gt;
    t1 = CORE_GetSysTick();&lt;br /&gt;
&lt;br /&gt;
    z = x * y;&lt;br /&gt;
&lt;br /&gt;
    t2 = CORE_GetSysTick();&lt;br /&gt;
    CORE_SysTickDis();&lt;br /&gt;
&lt;br /&gt;
    dt = (t2 - t1) - 9; //9 Takt-Zyklen werden für die Messung gebraucht &lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Compiler-Optimierung===&lt;br /&gt;
Standardmäßig verwendet Em::Blocks keine Optimierung. Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; Categories: Optimization&#039;&#039;&#039;&#039;&#039; kann zwischen verschieden Optimierungen ausgewählt werden.&lt;br /&gt;
&lt;br /&gt;
==Booten aus dem SRAM==&lt;br /&gt;
STM32 Controller haben die Möglichkeit Code aus dem Flash als auch aus dem SRAM auszuführen. Um eine Anwenung per Debugger in des SRAM zu laden sind nur wenige Schritte erforderlich:&lt;br /&gt;
&lt;br /&gt;
*Um das Linkerscript für den SRAM zu verwenden geht man zu: &#039;&#039;&#039;&#039;&#039;Build options... -&amp;gt; Device&#039;&#039;&#039;&#039;&#039; dort wählt man unter &#039;&#039;&#039;&#039;&#039;Policy&#039;&#039;&#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;Use target settings&#039;&#039;&#039;&#039;&#039; aus und übernimmt die vorherigen Einstellungen, nur unter &#039;&#039;&#039;&#039;&#039;Linker script*&#039;&#039;&#039;&#039;&#039; gibt man &#039;&#039;&#039;&#039;&#039;.\stm32f407vg_sram.ld&#039;&#039;&#039;&#039;&#039; an&lt;br /&gt;
&lt;br /&gt;
*Dann muss man noch unter &#039;&#039;&#039;&#039;&#039;Debug -&amp;gt; Interfaces -&amp;gt; Settings&#039;&#039;&#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;Vector table start&#039;&#039;&#039;&#039;&#039; auf 0x20000000 ändern und &#039;&#039;&#039;&#039;&#039;Execute from RAM&#039;&#039;&#039;&#039;&#039; auswählen.&lt;br /&gt;
&lt;br /&gt;
Anschließend kann man die Anwendung ganz normal debuggen. Nach einem Reset muss die Anwenung erneut mit dem Debugger gestartet werden.&lt;br /&gt;
&lt;br /&gt;
=Fortsetzung folgt..=&lt;br /&gt;
Kritik, Wünsche usw. sind gerne erwünscht, am besten hier in den Thread posten: [http://www.mikrocontroller.net/topic/323750 Neues STM32 Tutorial]&lt;br /&gt;
&lt;br /&gt;
[[Category:ARM]]&lt;br /&gt;
[[Category:STM32]]&lt;/div&gt;</summary>
		<author><name>Avrprogger</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=STM32_-_Einstieg_mit_Em::Blocks&amp;diff=81522</id>
		<title>STM32 - Einstieg mit Em::Blocks</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=STM32_-_Einstieg_mit_Em::Blocks&amp;diff=81522"/>
		<updated>2014-02-10T21:26:08Z</updated>

		<summary type="html">&lt;p&gt;Avrprogger: dsf&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In diesem Tutorial werde ich versuchen, möglichst einfach, die ersten Schritte zur Entwicklung von STM32 Anwenungen mit der Em::Blocks IDE zu erklären. Hier soll nicht so stark auf die einzelnen Peripherie-Module der Controller eingegangen werden, sondern mehr auf die IDE und die verschieden Libraries, wie die CMSIS Library, die DSP-Library, die Standard-Peripheral-Library, die USB-Library und vllt. über Ethernet. Ich denke ein Kapitel zu FreeRTOS wird es auch geben. Auserdem steht im Vordergrund Sachen wie z.B. booten aus dem SRAM, In-Application-Programming, FPU, Core-Coupled-RAM usw. Mal sehn wie weit ich komme ;)&lt;br /&gt;
&lt;br /&gt;
==Die Entwicklungsumgebung==&lt;br /&gt;
===Hardware===&lt;br /&gt;
Zum testen der Anwendungen, benutze ich das STM32F4-Discovery Board, welches einen Debugger, Peripherie und natürlich einen STM32 Controller (STM32F407VGT6) enthält. Deshalb sind alle Beispiele hier für den STM32F407VG Controller ausgelegt, können aber meisten 1:1 auf andere Controller portiert werden. Ich werde auch möglichsts keine STM32F4-Discovery Board spezifischen Libraries verwenden, damit der Portierungs-Vorgang möglichsts einfach bleibt.&lt;br /&gt;
&lt;br /&gt;
===Software===&lt;br /&gt;
In diesem Tutorial verwende ich [http://www.emblocks.org/ Em::Blocks] als IDE. Em::Blocks ist eine kostenlose, uneingeschränkte IDE, die alle STM32 Mikrcontroller unterstützt und sehr einfach zu bedienen ist.&lt;br /&gt;
nach dem Download kann die IDE per Dialog, sehr einfach, installiert werden. Als Compiler beinhaltet Em::Blocks den &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
Die IDE unterstützt zurzeit den ST-Link, den J-Link und es gibt eine Generic-Vorlage, durch welche andere Debugger konfiguriert werden können.&lt;br /&gt;
&lt;br /&gt;
Außerdem muss noch der passende Treiber für den Debugger installiert werden. Verwendet man ein Discovery-Board muss der [http://www.st.com/web/catalog/tools/FM146/CL1984/SC724/SS1677/PF251168 ST-Link/V2]-Treiber heruntergeladen und installiert werden. (Die Installation muss evtl. als Administrator ausgeführt werden, da sonst die Installation unvollständig wird.) Nach der Installation des Treibers kann man den Debugger über die entsprechende USB Schnittstelle an den PC anschließen und es sollte die Meldung von Windows kommen, dass der richtige Treiber gefunden wurde.&lt;br /&gt;
&lt;br /&gt;
===Libraries===&lt;br /&gt;
Zum programmieren benötigt man noch die [http://www.arm.com/products/processors/cortex-m/cortex-microcontroller-software-interface-standard.php CMSIS] und die Standard-Peripheral-Library (z.B. für die F4 Controller [http://www.st.com/stonline/stappl/productcatalog/app?page=partNumberSearchPage&amp;amp;levelid=SS1577&amp;amp;parentid=1743&amp;amp;resourcetype=SW Standard-Peripheral-Library-F4]), die man am besten in einen Ordner (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\STM32&#039;&#039;&#039;&#039;&#039;) entpackt&lt;br /&gt;
&lt;br /&gt;
==Basis-Wissen zur IDE==&lt;br /&gt;
Einige Grundfunktionalitäten der IDE:&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von Dateien zum Projekt===&lt;br /&gt;
Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf &amp;lt;ProjektName&amp;gt; -&amp;gt; Add files...&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Enfernen von Dateien aus dem Projekt===&lt;br /&gt;
Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf die Datei / mehrere Dateien auswählen -&amp;gt; Remove file from project&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
Die Dateien werden lediglich aus dem Projekt entfernt und nicht von der Festplatte gelöscht.&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von Include-Pfaden===&lt;br /&gt;
Sofern die Include-Datei(en) nicht im standard Include-Ordner &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; des Projektes liegen, muss man den Pfad zum Projekt hinzufügen, damit der Compiler die Include-Dateien später auch finden kann. Man geht wie folgt vor: Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf &amp;lt;ProjektName&amp;gt; -&amp;gt; Build options... -&amp;gt; Search Directories -&amp;gt; Add&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Compilieren===&lt;br /&gt;
Entweder über das &#039;&#039;&#039;&#039;&#039;Build&#039;&#039;&#039;&#039;&#039; Menü oder über &#039;&#039;&#039;&#039;&#039;F7&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Um eine genau Ausgabe des Compiler-Aufrufes mit allen Argumenten zu bekommen, geht man im &#039;&#039;&#039;&#039;&#039;Settings&#039;&#039;&#039;&#039;&#039; Menü auf &#039;&#039;&#039;&#039;&#039;Tools...&#039;&#039;&#039;&#039;&#039; und dann auf &#039;&#039;&#039;&#039;&#039;Toolchain executables&#039;&#039;&#039;&#039;&#039;. Ganz unten, unter &#039;&#039;&#039;&#039;&#039;Logging&#039;&#039;&#039;&#039;&#039; kann man dann &#039;&#039;&#039;&#039;&#039;Full command line&#039;&#039;&#039;&#039;&#039; auswählen.&lt;br /&gt;
&lt;br /&gt;
===Debuggen===&lt;br /&gt;
*Als erstes den Debugger starten über das &#039;&#039;&#039;&#039;&#039;Debug&#039;&#039;&#039;&#039;&#039; Menü und &#039;&#039;&#039;&#039;&#039;Start/stop Debug Session&#039;&#039;&#039;&#039;&#039; oder über &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
*Danach läuft die Anwendung auf dem Controller und warten im &#039;&#039;&#039;&#039;&#039;Reset_Handler&#039;&#039;&#039;&#039;&#039; auf Einzelschritt- bzw. Run- Befehle (&#039;&#039;&#039;&#039;&#039;F5, F10, F11&#039;&#039;&#039;&#039;&#039; usw..(siehe &#039;&#039;&#039;&#039;&#039;Debug-Menü&#039;&#039;&#039;&#039;&#039; für alle Möglichkeiten))&lt;br /&gt;
&lt;br /&gt;
*Mit &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039; wird die Debug-Session auch wieder beendet&lt;br /&gt;
&lt;br /&gt;
*Unter &#039;&#039;&#039;&#039;&#039;Debug -&amp;gt; Interfaces -&amp;gt; Target settings&#039;&#039;&#039;&#039;&#039; können Eigenschaften, wie z.B &#039;&#039;&#039;&#039;&#039;Run to main()&#039;&#039;&#039;&#039;&#039; aktiviert werden.&lt;br /&gt;
&lt;br /&gt;
===Projekt als Template abspeichern===&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;File -&amp;gt; Save project as template...&#039;&#039;&#039;&#039;&#039;. Das Template erscheint dann im Projekt-Dialog unter &#039;&#039;&#039;&#039;&#039;User templates&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Das erste Projekt erstellen==&lt;br /&gt;
Hier erkläre ich, wie man am Besten (aus meiner Sicht), ein neues Projekt von Grund auf erstellt, sodass man hinterher, den Controller-Kern über die CMSIS-Library und die Peripherie über die Register steuern kann.&lt;br /&gt;
&lt;br /&gt;
===1. Projekt mit der IDE erstellen===&lt;br /&gt;
Nach der Installation der oben beschriebenen Komponenten erstellt man am besten ein Verzeichnis (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\EmBlocks&#039;&#039;&#039;&#039;&#039;), indem später alle Projekte gespeichert werden. Für Libraries kann man auch noch ein Verzeichnis (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\STM32&#039;&#039;&#039;&#039;&#039;) erstellen, wo alle Libraries gespeichert werden, die man für die Projekt brauchen.&lt;br /&gt;
&lt;br /&gt;
Als nächstes starten man EmBlocks. Bei dem ersten Start öffnet sich ein Fenster, wo verschiedene Compiler angezeigt werden, die Em::Blocks findet. Dort wählt man den &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039; aus und klickt &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039;. Nun sollte sich das Hauptfenster von Em::Blocks öffnen. Über &#039;&#039;&#039;&#039;&#039;Create a new Project&#039;&#039;&#039;&#039;&#039; oder &#039;&#039;&#039;&#039;&#039;File -&amp;gt; New -&amp;gt; Project&#039;&#039;&#039;&#039;&#039; ruft man den Projekt-Dialog auf und kann ein neues Projekt erzeugen.&lt;br /&gt;
&lt;br /&gt;
Auf der Ersten Seite wählen man den &#039;&#039;&#039;&#039;&#039;STmicro-ARM&#039;&#039;&#039;&#039;&#039; Projekt-Typ aus.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_1.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auf der nächsten Seite wird man darauf hingewiesen, dass das der entsprechende Projekt-Typ-Dialog ausgeführt wird. Hier kann man ein Häkchen bei &#039;&#039;&#039;&#039;&#039;Skip this page next time&#039;&#039;&#039;&#039;&#039; setzen und auf &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; klicken.&lt;br /&gt;
&lt;br /&gt;
Im nächsten Schritt wählen man das zuvor erstellt Verzeichnis unter &#039;&#039;&#039;&#039;&#039;Folder to create Project in&#039;&#039;&#039;&#039;&#039; aus, indem später alle Projekt gespeichert werden. Außerdem geben wir dem Projekt einen Namen (z.B. &#039;&#039;&#039;&#039;&#039;FirstProject&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_2.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danach muss man einen Compiler auswählen und bestimmen, welche Projekt-Konfigurationen erszeugt werden sollen. Unter &#039;&#039;&#039;&#039;&#039;Compiler&#039;&#039;&#039;&#039;&#039; wählt man &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039; und man kann das Häkchen bei &#039;&#039;&#039;&#039;&#039;Create &amp;quot;Release&amp;quot; configuration&#039;&#039;&#039;&#039;&#039; entfernen, da diese unnötig ist, die Debug-Konfiguration sollte eig. immer ausreichen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_3.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auf den folgenden Seite wird der Controller ausgewählt. Verwendet man ein STM32F4-Discovery Board müssen folgende Dinge gewählt werden: &#039;&#039;&#039;&#039;&#039;Cortex_M4 (F3xx - F4xx) -&amp;gt; STM32F4xx (Cortex M4 with FPU) -&amp;gt; STM32F407VG&#039;&#039;&#039;&#039;&#039;. Leider sind die Auswahl Möglichkeiten nicht ganz richtig, da auch die F3 Controller einen Cortex M4 Kern und eine FPU haben (Ist aber nicht so wichtig, ist nur eine formale Sache). Außerdem entfernt man das Häkchen bei &#039;&#039;&#039;&#039;&#039;Standard Peripherals Library&#039;&#039;&#039;&#039;&#039; (Wie man die Standard-Peripheral-Library einbindet und verwendet erkläre ich später). Man kann auch das Häkchen bei &#039;&#039;&#039;&#039;&#039;Create hex file for Realease target&#039;&#039;&#039;&#039;&#039; entfernen.&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;Stack Size&#039;&#039;&#039;&#039;&#039; und &#039;&#039;&#039;&#039;&#039;Heap Size&#039;&#039;&#039;&#039;&#039; wird die Größe von Stack und Heap festgelegt. Für eine erste Anwendung kann man die Einstellungen so lassen (Stack-Size: 0x0100 =&amp;gt; 256 Byte Stack und Heap-Size: 0x0000 =&amp;gt; kein Heap). Mit &#039;&#039;&#039;&#039;&#039;Finish&#039;&#039;&#039;&#039;&#039; ist der Projekt Dialog abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_4.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danach sollten sich zwei neue Fenster öffnen, um die Debug-Eigenschaften fest zu legen.&lt;br /&gt;
Verwendet man ein Discovery Board/ST-Link müssen die Einstellungen wie auf dem Bild gewählt werden. Über den Button &#039;&#039;&#039;&#039;&#039;Settings&#039;&#039;&#039;&#039;&#039; öffnet sich das zweite Fenster, falls sich dieses nicht schon von alleine öffnen sollte. Nach den Schließen der Fenster über &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; ist der Projekt Dialog beendet und ein neues Projekt steht zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_5_1.png|Debug Eigenschaften 1. Fenster]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_5_2.png|Debug Eigenschaften 2. Fenster]]&lt;br /&gt;
&lt;br /&gt;
===2. CMSIS-Library und Startup-Code hinzufügen===&lt;br /&gt;
Wenn man sich, nachdem man ein neues Projekt in der IDE erstellt hat, die bereits vorhandenen Dateien im Projekt ansieht, stellt man fest, das bereits ein Ordner &#039;&#039;&#039;&#039;&#039;cmsis&#039;&#039;&#039;&#039;&#039; existiert, der einige wichtige Include-Dateien der CMSIS-Library enthält. Allerdings sind das wirklich nur die wichtigsten Include-Dateien der CMSIS-Library und dazu noch, die aus einer älternen Version. Ich ziehe es deshalb vor die &amp;quot;Mini-CMSIS-Libraray&amp;quot; und die &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c/.h&#039;&#039;&#039;&#039;&#039; Dateien des Projektes durch aktuellere Versionen zu ersetzen. So ist später auch die Integration  von anderen Libraries, wie z.B. der CMSIS-DSP-Libarary einfacher.  &lt;br /&gt;
&lt;br /&gt;
Zunächst gehen man in das Projekt-Verzeichnis und löscht:&lt;br /&gt;
*Den Ordner &#039;&#039;&#039;&#039;&#039;cmsis&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Alle Dateien im Include Verzeichnis &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; im &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner&lt;br /&gt;
&lt;br /&gt;
Außerdem entfernt man auch alle gelöschten Dateien in der IDE aus dem Projekt mit &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Rechts Klick -&amp;gt; Remove file from project&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Es sollte folgende Verzeichnis Struktur überbleiben:&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_6.png|Überbleibende Dateien]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Jetzt müssen die gelöschten Dateien durch die aktuelleren ersetzt werden.&lt;br /&gt;
&lt;br /&gt;
*Dazu kopieren man den gesamten Ordner &#039;&#039;&#039;&#039;&#039;CMSIS&#039;&#039;&#039;&#039;&#039; aus dem CMSIS Download in das Projekt Verzeichnis.&lt;br /&gt;
&lt;br /&gt;
*Aus dem Standard-Peripheral-Library Download kopiert man von &#039;&#039;&#039;&#039;&#039;Libraries\CMSIS\Device\ST\STM32F4xx\Include&#039;&#039;&#039;&#039;&#039; alle Dateien in den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projekt Verzeichnisses&lt;br /&gt;
&lt;br /&gt;
*Aus der Standard-Peripheral-Library kopieren man ebenfalls von &#039;&#039;&#039;&#039;&#039;Libraries\CMSIS\Device\ST\STM32F4xx\Source\Templates&#039;&#039;&#039;&#039;&#039; die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; in den &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner des Projekts&lt;br /&gt;
&lt;br /&gt;
Anschließend müssen die neuen Dateien in der IDE dem Projekt hinzugefügt werden. Dazu benutzt man &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Rechts Klick -&amp;gt; Add files&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
*Aus dem &#039;&#039;&#039;&#039;&#039;CMSIS&#039;&#039;&#039;&#039;&#039; Ordner im Projekt Verzeichnis werden aus den Unterorder &#039;&#039;&#039;&#039;&#039;Include&#039;&#039;&#039;&#039;&#039; folgende Dateien dem Projekt hinzugefügt:&lt;br /&gt;
**arm_common_tables.h&lt;br /&gt;
**arm_const_structs.h&lt;br /&gt;
**arm_math.h&lt;br /&gt;
**core_cm4.h&lt;br /&gt;
**core_cm4_simd.h&lt;br /&gt;
**core_cmFunc.h&lt;br /&gt;
**core_cmInstr.h&lt;br /&gt;
*Alle Dateien aus den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projektes&lt;br /&gt;
*Die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; aus dem &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner&lt;br /&gt;
&lt;br /&gt;
So sollte die Struktur dann aussehen:&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_7.png|Anwenungs-Grundgerüst]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Da einige Dateien der Libraries später bearbeitet werden müssen und Schreibgeschützt sind, weise ich hier schonmal darauf hin, das der Schreibschutz in der IDE über &#039;&#039;&#039;&#039;&#039;Rechts Klick auf die Datei -&amp;gt; Properties -&amp;gt; Häkchen bei &amp;quot;File is read only&amp;quot; entfernen&#039;&#039;&#039;&#039;&#039; entfert werden kann.&lt;br /&gt;
&lt;br /&gt;
Damit die IDE die Header-Dateien der CMSIS Library auch finden kann, weil diese ja nicht im standard Include Ordner &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; liegen, muss unter &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Build Options -&amp;gt; Search Directories&#039;&#039;&#039;&#039;&#039; der Pfad &#039;&#039;&#039;&#039;&#039;CMSIS\Include&#039;&#039;&#039;&#039;&#039; hinzugefügt werden.&lt;br /&gt;
&lt;br /&gt;
Compiliert man jetzt das Projekt mit &#039;&#039;&#039;&#039;&#039;F7&#039;&#039;&#039;&#039;&#039; gibt es ein paar Fehler Meldungen, weil keine Controller-Reihe ausgewählt wurde. Ebenfalls unter &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Build Options -&amp;gt; Compiler Settings -&amp;gt; #defines&#039;&#039;&#039;&#039;&#039; wird der Define &#039;&#039;&#039;&#039;&#039;STM32F40_41xxx&#039;&#039;&#039;&#039;&#039; hinzugefügt.&lt;br /&gt;
&lt;br /&gt;
Beim erneuten Compilieren sollten sich nun keine neuen Fehler ergeben.&lt;br /&gt;
&lt;br /&gt;
===Das erste Programm===&lt;br /&gt;
Nachdem ein grundsätzliches &amp;quot;Gerüst&amp;quot; fertig ist, kann man den ersten Code schreiben.&lt;br /&gt;
main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC-&amp;gt;AHB1ENR |= RCC_AHB1ENR_GPIODEN;    //Takt für GPIO aktivieren&lt;br /&gt;
    GPIOD-&amp;gt;MODER |= GPIO_MODER_MODER15_0;   //GPIOD Pin15 als Ausgang&lt;br /&gt;
    GPIOD-&amp;gt;BSRRL |= GPIO_BSRR_BS_15;        //GPIOD Pin15 auf High ziehen&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039; wird dann der Debugger gestartet. Hat der Debugger das Projekt erfolgreich übertragen kann die Ausführung mit &#039;&#039;&#039;&#039;&#039;F5&#039;&#039;&#039;&#039;&#039; begonnen werden.&lt;br /&gt;
&lt;br /&gt;
==Libraries einbinden/verwenden==&lt;br /&gt;
===Einbinden der Standard-Peripheral-Library===&lt;br /&gt;
Um nicht immer die einzelnen Register, wie im ersten &amp;quot;bare-metal&amp;quot; Beispiel, aus dem Reference-Manual zu suchen und zu beschreiben, gibt es von ST die Standard Peripheral Library, die diese Aufgaben übernimmt und mit der sich die &amp;quot;normale/grundlegende&amp;quot; (Alles außer USB und Ethernet) Peripherie recht einfach steuern lässt. Um die Library zu verwenden erzeugt man wie oben beschrieben ein neues Grundgerüst und kopiert als erstes den Ordner &#039;&#039;&#039;&#039;&#039;Libraries\STM32F4xx_StdPeriph_Driver&#039;&#039;&#039;&#039;&#039; aus dem Standard-Peripheral-Library Download in das Projekt-Verzeichnis. Außerdem muss man die Datei &#039;&#039;&#039;&#039;&#039;Project\STM32F4xx_StdPeriph_Templates\stm32f4xx_conf.h&#039;&#039;&#039;&#039;&#039; ebenfalls aus dem Standard-Peripheral-Library Download in den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projektes kopieren. In der IDE fügt man den Include-Path &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\inc&#039;&#039;&#039;&#039;&#039; hinzufügen, wie bei der CMSIS-Library (s.o.).&lt;br /&gt;
Außerdem muss noch &#039;&#039;&#039;&#039;&#039;USE_STDPERIPH_DRIVER&#039;&#039;&#039;&#039;&#039; als Define in der IDE hinzugefügt werden (s.o.).&lt;br /&gt;
Danach fügt man die Source- und Include-Dateien aus dem Ordner &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\inc&#039;&#039;&#039;&#039;&#039; und &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\src&#039;&#039;&#039;&#039;&#039; dem Project mit &#039;&#039;&#039;&#039;&#039;&amp;lt;Project Name&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Add files&#039;&#039;&#039;&#039;&#039; hinzu, allerdings nur die, für welche auch der Controller die entsprechende Peripherie besitzt. Beim STM32F4-Discovery Board / STM32F407VG Controller dürfen also nicht folgende Dateien nicht mit hinzugefügt werden, weil diese Peripherie nur bei anderen Controller vorhanden ist:&lt;br /&gt;
&lt;br /&gt;
*stm32f4xx_dma2d.c/.h&lt;br /&gt;
*stm32f4xx_fmc.c/.h&lt;br /&gt;
*stm32f4xx_ltdc.c/.h&lt;br /&gt;
*stm32f4xx_sai.c/.h&lt;br /&gt;
&lt;br /&gt;
Daraus resultiert folgende Struktur:&lt;br /&gt;
&lt;br /&gt;
[[Datei:stdperiphlib_2.png|Header-Struktur]] [[Datei:stdperiphlib_1.png|Source-Struktur]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Anschließen kann die Standard-Peripheral-Library benutz werden.&lt;br /&gt;
main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);&lt;br /&gt;
&lt;br /&gt;
    GPIO_InitTypeDef GPIOD_InitStructure;&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Mode = GPIO_Mode_OUT;     //Als Ausgang&lt;br /&gt;
    GPIOD_InitStructure.GPIO_OType = GPIO_OType_PP;    //Push-Pull Betrieb&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Pin = GPIO_Pin_15;        //Pin 15 (STM32F4-Discovery: Blaue LED)&lt;br /&gt;
    GPIOD_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;  //Kein Pull-Up oder Pull-Down Widerstand aktiviert&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Speed = GPIO_Speed_25MHz; //25MHz Update-Rate&lt;br /&gt;
    GPIO_Init(GPIOD, &amp;amp;GPIOD_InitStructure);&lt;br /&gt;
&lt;br /&gt;
    GPIO_SetBits(GPIOD, GPIO_Pin_15);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Startup-Code, Linker-Script, Takt, FPU, Optimierung usw.==&lt;br /&gt;
===Startup-Code===&lt;br /&gt;
Em::Blocks fügt standardmäßig einen Startup-Code mit in das Projekt ein. Die wichtigsten Dinge die darin erledigt werden sind folgende:&lt;br /&gt;
&lt;br /&gt;
*Stack und Heap wird angelgt&lt;br /&gt;
*Die Vector-Table wird angelegt&lt;br /&gt;
*Ein Default Reset-Handler wird implementiert, dieser erledigt folgende aufgaben:&lt;br /&gt;
**Kopieren der definierten Daten aus dem Flash in den SRAM&lt;br /&gt;
**&#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; wird aufgerfen, wenn &#039;&#039;&#039;&#039;&#039;__NO_SYSTEM_INIT&#039;&#039;&#039;&#039;&#039; nicht definiert ist&lt;br /&gt;
**Sprung in die &#039;&#039;&#039;&#039;&#039;main()&#039;&#039;&#039;&#039;&#039; Funktion&lt;br /&gt;
*Allen anderen Interrupt-Handler wird eine Default-Funktion &#039;&#039;&#039;&#039;&#039;def_irq_handler&#039;&#039;&#039;&#039;&#039; mit einer &#039;&#039;&#039;&#039;&#039;while(1)&#039;&#039;&#039;&#039;&#039;-Schleife zugewiesen, falls kein anderer Interrupt-Handler existiert.&lt;br /&gt;
&lt;br /&gt;
Normalerweise muss am Startup-Code nichts verändert werden.&lt;br /&gt;
&lt;br /&gt;
===Linker-Script===&lt;br /&gt;
Em::Blocks stellt zwei fertige Linker-Scripts bereit, eins für die Ausführung des Programmes aus dem Flash (&#039;&#039;&#039;&#039;&#039;*_flash.ld&#039;&#039;&#039;&#039;&#039;), das andere für die Ausführung aus dem SRAM (&#039;&#039;&#039;&#039;&#039;*_sram.ld&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Normalerweise muss auch hier nichts geändert werden, es sei den Daten sollen in bestimmten Adressbereichen abgelegt werden (z.B. im Core-Coupled RAM), was ich später noch zum Tutorial hinzufüge.&lt;br /&gt;
&lt;br /&gt;
===Der Takt===&lt;br /&gt;
Jeder Controller oder Prozessor braucht einen Takt, indem er die einzelnen Maschinen-Befehle abarbeiten kann.&lt;br /&gt;
Bei den STM32 Mikrocontrollern kann dieser Takt aus verschiedenen Quellen kommen:&lt;br /&gt;
&lt;br /&gt;
1. High Speed Internal Oszillator (HSI)&lt;br /&gt;
&lt;br /&gt;
2. High Speed External Oszillator (HSE)&lt;br /&gt;
&lt;br /&gt;
3. Low Speed Internal Oszillator (LSI)&lt;br /&gt;
&lt;br /&gt;
4. Low Speed External Oszillator (LSE)&lt;br /&gt;
&lt;br /&gt;
5. Phase-Locked Loop (PLL) (generiert den Takt aus den ersten vier Taktquellen durch Teiler und Faktoren)&lt;br /&gt;
&lt;br /&gt;
Nach einem Reset wird der Controller aus der HSI Taktquelle versorgt (16MHz beim STM32F407VG). Um die voll Performance des Controllers zu erreichen muss die PLL verwendet werden, welche den Takt durch geschickte Teiler und Faktoren vervielfältigt, sodass am Ende der Controller mit der maximalen Taktfrequenz läuft. Die notwendige Initialisierung der PLL findet in der Funktion &#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; statt. Die PLL erzeugt zunächst einen Basistakt:&lt;br /&gt;
&lt;br /&gt;
PLL_VCO = (F_HSE / PLL_M) * PLL_N&lt;br /&gt;
&lt;br /&gt;
Aus diesem Takt wird dann der Takt für den Controller-Kern abgeleitet:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = PLL_VCO / PLL_P&lt;br /&gt;
&lt;br /&gt;
Und der Takt für SDIO / USB / RNG (48MHz):&lt;br /&gt;
&lt;br /&gt;
48MHz = PLL_VCO / PLL_Q&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Durch weiter Teiler werden, die Takte für die einzelnen Busse erzeugt, da diese nicht alle beliebig schnell betrieben werden dürfen.&lt;br /&gt;
&lt;br /&gt;
Genaue Angaben findet man zu dem jeweiligen Clock-System des Controllers im Reference Manual.&lt;br /&gt;
&lt;br /&gt;
Ein Blick in den &amp;quot;Kommentar-Header&amp;quot; verrät, dass von einem externen (HSE) Oszillator von 25MHz ausgegangen wird, der die PLL versorgen soll.&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((25MHz / PLL_M(25)) * PLL_N(336)) / PLL_P(2) = 168MHz&lt;br /&gt;
&lt;br /&gt;
Allerdings stimmt diese Rechnung natürlich nur, wenn wirklich ein 25MHz Quarz am Controller angeschlossen ist. Auf dem STM32F4-Discovery Board befindet sich aber nur ein 8MHz Quarz. Demnach gilt:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((8MHz / PLL_M(25)) * PLL_N(336)) / PLL_P(2) = 53.76MHz&lt;br /&gt;
&lt;br /&gt;
Der Controller läuft also nur mit 53.76MHz, wenn wie ober beschrieben ein Projekt erstellt wird. Allerdings kann dieses Problem durch ändern von den betroffen Defines behoben werden:&lt;br /&gt;
 &lt;br /&gt;
*Dazu geht man in die &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; Datei und passt zur Vollständigkeit erstmal die zum Controller passende Tabelle im &amp;quot;Kommentar-Header&amp;quot; an (Z.57f):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      HSE Frequency(Hz)                      | 8000000&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      PLL_M                                  | 8&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Danach passt man den PPL_M Define (Z.254) an:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/************************* PLL Parameters *************************************/&lt;br /&gt;
/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */&lt;br /&gt;
#define PLL_M      8&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Außerdem muss man den HSE_VALUE Define in der &#039;&#039;&#039;&#039;&#039;inc/stm32f4xx.h&#039;&#039;&#039;&#039;&#039; angepasst werden (Z.122):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#if !defined  (HSE_VALUE)&lt;br /&gt;
  #define HSE_VALUE    ((uint32_t)8000000) /*!&amp;lt; Value of the External oscillator in Hz */&lt;br /&gt;
&lt;br /&gt;
#endif /* HSE_VALUE */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine neue Berechnung zeigt:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((8MHz / PLL_M(8)) * PLL_N(336)) / PLL_P(2) = 168MHz&lt;br /&gt;
&lt;br /&gt;
Jetzt läuft der Controller mit maximaler Geschwindigkeit.&lt;br /&gt;
&lt;br /&gt;
Die Theorie wird durch folgendes Programm verifiziert. Der geviertelte System-Takt SYSCLK wir am Pin PC9 ausgegeben. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);&lt;br /&gt;
&lt;br /&gt;
    GPIO_InitTypeDef GPIOC_InitStructure;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Mode = GPIO_Mode_AF;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_OType = GPIO_OType_PP;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Pin = GPIO_Pin_9;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;&lt;br /&gt;
    GPIO_Init(GPIOC, &amp;amp;GPIOC_InitStructure);&lt;br /&gt;
&lt;br /&gt;
    RCC_MCO2Config(RCC_MCO2Source_SYSCLK, RCC_MCO2Div_4);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Die FPU===&lt;br /&gt;
====Allgemeines====&lt;br /&gt;
Damit die FPU richtig verwendet wird, müssen normalerweise zwei Bedingungen erfüllt sein:&lt;br /&gt;
&lt;br /&gt;
1. Der Controller muss in der Initialisierung-Funktion &#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; in &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; die FPU Hardware-seitig aktivieren&lt;br /&gt;
&lt;br /&gt;
2. Damit die FPU auch was zu tuen bekommt, müssen vom Compiler FPU-Instructions erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
Die Em::Blocks IDE verwendet standardmäßig die FPU, wenn eine Vorhanden ist. Hier wird die FPU Hardware-seitig aktiviert (&#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; Z.341):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* FPU settings ------------------------------------------------------------*/&lt;br /&gt;
  #if (__FPU_PRESENT == 1) &amp;amp;&amp;amp; (__FPU_USED == 1)&lt;br /&gt;
    SCB-&amp;gt;CPACR |= ((3UL &amp;lt;&amp;lt; 10*2)|(3UL &amp;lt;&amp;lt; 11*2));  /* set CP10 and CP11 Full Access */&lt;br /&gt;
  #endif&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
__FPU_PRESENT wird in der &#039;&#039;&#039;&#039;&#039;stm32f4xx.h&#039;&#039;&#039;&#039;&#039; definiert.&lt;br /&gt;
__FPU_USED wird von der IDE übernommen (siehe Build-Log): &#039;&#039;&#039;&#039;&#039;-D__FPU_USED&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Außerdem wird der Compiler von der IDE standardmäßig mit dem Argument &#039;&#039;&#039;&#039;&#039;-mfloat-abi=hard&#039;&#039;&#039;&#039;&#039; aufgerufen, wodurch FPU-Instructions erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
====FPU abschalten====&lt;br /&gt;
Um die FPU ab zu schalten (Mir würde jetzt nur Strom sparen als Grund einfallen) geht man wie folgt vor:&lt;br /&gt;
&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick Build options -&amp;gt; Device -&amp;gt; Policy&#039;&#039;&#039;&#039;&#039; wählt man &#039;&#039;&#039;&#039;&#039;Use target settings&#039;&#039;&#039;&#039;&#039; und über nimmt die Einstellungen, die vorher dort eingetragen waren, allerdings lässt man das Feld &#039;&#039;&#039;&#039;&#039;FP-hardware&#039;&#039;&#039;&#039;&#039; frei.&lt;br /&gt;
&lt;br /&gt;
[[Datei:fpu_1.png|FPU Abschalten Schritt 1]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;Compiler Settings -&amp;gt; Policy&#039;&#039;&#039;&#039;&#039; wählt man dann &#039;&#039;&#039;&#039;&#039;Use target options only&#039;&#039;&#039;&#039;&#039;. Dann kann man unter &#039;&#039;&#039;&#039;&#039;Categories&#039;&#039;&#039;&#039;&#039; die Option &#039;&#039;&#039;&#039;&#039;ARM FPU architecture&#039;&#039;&#039;&#039;&#039; auswählen. Dort stehen dann drei Möglichkeiten für die FPU zur Verfügung:&lt;br /&gt;
&lt;br /&gt;
1. Software-FPU-Library für Gleitkomma-Berechnung verwenden - Keine FPU-Instructions werden generiert (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=soft&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
2. Eine Mischung aus Software- und Hardware-FPU wird verwendet (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=softfp&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
3. Hardware-FPU wird für Gleitkomma-Berechnungen verwendet (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=hard&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
[[Datei:fpu_2.png|FPU Abschalten Schritt 2]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Um die FPU ab zu schalten wählt man natürlich die erste Möglichkeit.&lt;br /&gt;
Bei der 2. und 3. Möglichkeit fügt die IDE auch den Define &#039;&#039;&#039;&#039;&#039;__FPU_USED&#039;&#039;&#039;&#039;&#039; hinzu. Bei Der ersten Möglichkeit nicht. Der Code muss also nicht verändert / auskommentiert werden.&lt;br /&gt;
&lt;br /&gt;
Um die FPU wieder zu aktivieren müssen alle Schritte wieder rückgängig gemacht werden.&lt;br /&gt;
&lt;br /&gt;
Am besten ist es einfach mal alle Möglichkeiten im Einzelschritt durch zu probieren. Dann stellt man schnell fest, ob die FPU aktiviert wir oder nicht. Ein Blick in den erweiterten &#039;&#039;&#039;&#039;&#039;Build-Log&#039;&#039;&#039;&#039;&#039; gibt auch schnell Aufschluss darüber, wie der Compiler aufgerufen wird (siehe Kapitel [http://www.mikrocontroller.net/articles/STM32_-_Einstieg_mit_Em::Blocks#Compilieren Compilieren]).&lt;br /&gt;
&lt;br /&gt;
====Test Programm für die FPU====&lt;br /&gt;
Hier ein kleines Testprogramm, dass misst wie viele Taktzyklen für eine Gleitkomma-Multiplikation gebraucht werden. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define CORE_SysTickEn()    (*((u32*)0xE0001000)) = 0x40000001&lt;br /&gt;
#define CORE_SysTickDis()   (*((u32*)0xE0001000)) = 0x40000000&lt;br /&gt;
#define CORE_GetSysTick()   (*((u32*)0xE0001004))&lt;br /&gt;
&lt;br /&gt;
uint32_t t1, t2, dt;&lt;br /&gt;
float x, y, z;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    x = 53.64f;&lt;br /&gt;
    y = 0.27f;&lt;br /&gt;
&lt;br /&gt;
    CORE_SysTickEn();&lt;br /&gt;
    t1 = CORE_GetSysTick();&lt;br /&gt;
&lt;br /&gt;
    z = x * y;&lt;br /&gt;
&lt;br /&gt;
    t2 = CORE_GetSysTick();&lt;br /&gt;
    CORE_SysTickDis();&lt;br /&gt;
&lt;br /&gt;
    dt = (t2 - t1) - 9; //9 Takt-Zyklen werden für die Messung gebraucht &lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Compiler-Optimierung===&lt;br /&gt;
Standardmäßig verwendet Em::Blocks keine Optimierung. Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; Categories: Optimization&#039;&#039;&#039;&#039;&#039; kann zwischen verschieden Optimierungen ausgewählt werden.&lt;br /&gt;
&lt;br /&gt;
==Booten aus dem SRAM==&lt;br /&gt;
STM32 Controller haben die Möglichkeit Code aus dem Flash als auch aus dem SRAM auszuführen. Um eine Anwenung per Debugger in des SRAM zu laden sind nur wenige Schritte erforderlich:&lt;br /&gt;
&lt;br /&gt;
*Um das Linkerscript für den SRAM zu verwenden geht man zu: &#039;&#039;&#039;&#039;&#039;Build options... -&amp;gt; Device&#039;&#039;&#039;&#039;&#039; dort wählt man unter &#039;&#039;&#039;&#039;&#039;Policy&#039;&#039;&#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;Use target settings&#039;&#039;&#039;&#039;&#039; aus und übernimmt die vorherigen Einstellungen, nur unter &#039;&#039;&#039;&#039;&#039;Linker script*&#039;&#039;&#039;&#039;&#039; gibt man &#039;&#039;&#039;&#039;&#039;.\stm32f407vg_sram.ld&#039;&#039;&#039;&#039;&#039; an&lt;br /&gt;
&lt;br /&gt;
*Dann muss man noch unter &#039;&#039;&#039;&#039;&#039;Debug -&amp;gt; Interfaces -&amp;gt; Settings&#039;&#039;&#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;Vector table start&#039;&#039;&#039;&#039;&#039; auf 0x20000000 ändern und &#039;&#039;&#039;&#039;&#039;Execute from RAM&#039;&#039;&#039;&#039;&#039; auswählen.&lt;br /&gt;
&lt;br /&gt;
Anschließend kann man die Anwendung ganz normal debuggen. Nach einem Reset muss die Anwenung erneut mit dem Debugger gestartet werden.&lt;br /&gt;
&lt;br /&gt;
=Fortsetzung folgt..=&lt;br /&gt;
Kritik, Wünsche usw. sind gerne erwünscht, am besten hier in den Thread posten: [http://www.mikrocontroller.net/topic/323750 Neues STM32 Tutorial]&lt;br /&gt;
&lt;br /&gt;
[[Category:ARM]]&lt;br /&gt;
[[Category:STM32]]&lt;/div&gt;</summary>
		<author><name>Avrprogger</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=STM32_-_Einstieg_mit_Em::Blocks&amp;diff=81521</id>
		<title>STM32 - Einstieg mit Em::Blocks</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=STM32_-_Einstieg_mit_Em::Blocks&amp;diff=81521"/>
		<updated>2014-02-10T21:25:11Z</updated>

		<summary type="html">&lt;p&gt;Avrprogger: cvb&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In diesem Tutorial werde ich versuchen, möglichst einfach, die ersten Schritte zur Entwicklung von STM32 Anwenungen mit der Em::Blocks IDE zu erklären. Hier soll nicht so stark auf die einzelnen Peripherie-Module der Controller eingegangen werden, sondern mehr auf die IDE und die verschieden Libraries, wie die CMSIS Library, die DSP-Library, die Standard-Peripheral-Library, die USB-Library und vllt. über Ethernet. Ich denke ein Kapitel zu FreeRTOS wird es auch geben. Auserdem steht im Vordergrund Sachen wie z.B. booten aus dem SRAM, In-Application-Programming, FPU, Core-Coupled-RAM usw. Mal sehn wie weit ich komme ;)&lt;br /&gt;
&lt;br /&gt;
==Die Entwicklungsumgebung==&lt;br /&gt;
===Hardware===&lt;br /&gt;
Zum testen der Anwendungen, benutze ich das STM32F4-Discovery Board, welches einen Debugger, Peripherie und natürlich einen STM32 Controller (STM32F407VGT6) enthält. Deshalb sind alle Beispiele hier für den STM32F407VG Controller ausgelegt, können aber meisten 1:1 auf andere Controller portiert werden. Ich werde auch möglichsts keine STM32F4-Discovery Board spezifischen Libraries verwenden, damit der Portierungs-Vorgang möglichsts einfach bleibt.&lt;br /&gt;
&lt;br /&gt;
===Software===&lt;br /&gt;
In diesem Tutorial verwende ich [http://www.emblocks.org/ Em::Blocks] als IDE. Em::Blocks ist eine kostenlose, uneingeschränkte IDE, die alle STM32 Mikrcontroller unterstützt und sehr einfach zu bedienen ist.&lt;br /&gt;
nach dem Download kann die IDE per Dialog, sehr einfach, installiert werden. Als Compiler beinhaltet Em::Blocks den &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
Die IDE unterstützt zurzeit den ST-Link, den J-Link und es gibt eine Generic-Vorlage, durch welche andere Debugger konfiguriert werden können.&lt;br /&gt;
&lt;br /&gt;
Außerdem muss noch der passende Treiber für den Debugger installiert werden. Verwendet man ein Discovery-Board muss der [http://www.st.com/web/catalog/tools/FM146/CL1984/SC724/SS1677/PF251168 ST-Link/V2]-Treiber heruntergeladen und installiert werden. (Die Installation muss evtl. als Administrator ausgeführt werden, da sonst die Installation unvollständig wird.) Nach der Installation des Treibers kann man den Debugger über die entsprechende USB Schnittstelle an den PC anschließen und es sollte die Meldung von Windows kommen, dass der richtige Treiber gefunden wurde.&lt;br /&gt;
&lt;br /&gt;
===Libraries===&lt;br /&gt;
Zum programmieren benötigt man noch die [http://www.arm.com/products/processors/cortex-m/cortex-microcontroller-software-interface-standard.php CMSIS] und die Standard-Peripheral-Library (z.B. für die F4 Controller [http://www.st.com/stonline/stappl/productcatalog/app?page=partNumberSearchPage&amp;amp;levelid=SS1577&amp;amp;parentid=1743&amp;amp;resourcetype=SW Standard-Peripheral-Library-F4]), die man am besten in einen Ordner (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\STM32&#039;&#039;&#039;&#039;&#039;) entpackt&lt;br /&gt;
&lt;br /&gt;
==Basis-Wissen zur IDE==&lt;br /&gt;
Einige Grundfunktionalitäten der IDE:&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von Dateien zum Projekt===&lt;br /&gt;
Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf &amp;lt;ProjektName&amp;gt; -&amp;gt; Add files...&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Enfernen von Dateien aus dem Projekt===&lt;br /&gt;
Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf die Datei / mehrere Dateien auswählen -&amp;gt; Remove file from project&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
Die Dateien werden lediglich aus dem Projekt entfernt und nicht von der Festplatte gelöscht.&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von Include-Pfaden===&lt;br /&gt;
Sofern die Include-Datei(en) nicht im standard Include-Ordner &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; des Projektes liegen, muss man den Pfad zum Projekt hinzufügen, damit der Compiler die Include-Dateien später auch finden kann. Man geht wie folgt vor: Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf &amp;lt;ProjektName&amp;gt; -&amp;gt; Build options... -&amp;gt; Search Directories -&amp;gt; Add&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Compilieren===&lt;br /&gt;
Entweder über das &#039;&#039;&#039;&#039;&#039;Build&#039;&#039;&#039;&#039;&#039; Menü oder über &#039;&#039;&#039;&#039;&#039;F7&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Um eine genau Ausgabe des Compiler-Aufrufes mit allen Argumenten zu bekommen, geht man im &#039;&#039;&#039;&#039;&#039;Settings&#039;&#039;&#039;&#039;&#039; Menü auf &#039;&#039;&#039;&#039;&#039;Tools...&#039;&#039;&#039;&#039;&#039; und dann auf &#039;&#039;&#039;&#039;&#039;Toolchain executables&#039;&#039;&#039;&#039;&#039;. Ganz unten, unter &#039;&#039;&#039;&#039;&#039;Logging&#039;&#039;&#039;&#039;&#039; kann man dann &#039;&#039;&#039;&#039;&#039;Full command line&#039;&#039;&#039;&#039;&#039; auswählen.&lt;br /&gt;
&lt;br /&gt;
===Debuggen===&lt;br /&gt;
*Als erstes den Debugger starten über das &#039;&#039;&#039;&#039;&#039;Debug&#039;&#039;&#039;&#039;&#039; Menü und &#039;&#039;&#039;&#039;&#039;Start/stop Debug Session&#039;&#039;&#039;&#039;&#039; oder über &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
*Danach läuft die Anwendung auf dem Controller und warten im &#039;&#039;&#039;&#039;&#039;Reset_Handler&#039;&#039;&#039;&#039;&#039; auf Einzelschritt- bzw. Run- Befehle (&#039;&#039;&#039;&#039;&#039;F5, F10, F11&#039;&#039;&#039;&#039;&#039; usw..(siehe &#039;&#039;&#039;&#039;&#039;Debug-Menü&#039;&#039;&#039;&#039;&#039; für alle Möglichkeiten))&lt;br /&gt;
&lt;br /&gt;
*Mit &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039; wird die Debug-Session auch wieder beendet&lt;br /&gt;
&lt;br /&gt;
*Unter &#039;&#039;&#039;&#039;&#039;Debug -&amp;gt; Interfaces -&amp;gt; Target settings&#039;&#039;&#039;&#039;&#039; können Eigenschaften, wie z.B &#039;&#039;&#039;&#039;&#039;Run to main()&#039;&#039;&#039;&#039;&#039; aktiviert werden.&lt;br /&gt;
&lt;br /&gt;
===Projekt als Template abspeichern===&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;File -&amp;gt; Save project as template...&#039;&#039;&#039;&#039;&#039;. Das Template erscheint dann im Projekt-Dialog unter &#039;&#039;&#039;&#039;&#039;User templates&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Das erste Projekt erstellen==&lt;br /&gt;
Hier erkläre ich, wie man am Besten (aus meiner Sicht), ein neues Projekt von Grund auf erstellt, sodass man hinterher, den Controller-Kern über die CMSIS-Library und die Peripherie über die Register steuern kann.&lt;br /&gt;
&lt;br /&gt;
===1. Projekt mit der IDE erstellen===&lt;br /&gt;
Nach der Installation der oben beschriebenen Komponenten erstellt man am besten ein Verzeichnis (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\EmBlocks&#039;&#039;&#039;&#039;&#039;), indem später alle Projekte gespeichert werden. Für Libraries kann man auch noch ein Verzeichnis (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\STM32&#039;&#039;&#039;&#039;&#039;) erstellen, wo alle Libraries gespeichert werden, die man für die Projekt brauchen.&lt;br /&gt;
&lt;br /&gt;
Als nächstes starten man EmBlocks. Bei dem ersten Start öffnet sich ein Fenster, wo verschiedene Compiler angezeigt werden, die Em::Blocks findet. Dort wählt man den &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039; aus und klickt &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039;. Nun sollte sich das Hauptfenster von Em::Blocks öffnen. Über &#039;&#039;&#039;&#039;&#039;Create a new Project&#039;&#039;&#039;&#039;&#039; oder &#039;&#039;&#039;&#039;&#039;File -&amp;gt; New -&amp;gt; Project&#039;&#039;&#039;&#039;&#039; ruft man den Projekt-Dialog auf und kann ein neues Projekt erzeugen.&lt;br /&gt;
&lt;br /&gt;
Auf der Ersten Seite wählen man den &#039;&#039;&#039;&#039;&#039;STmicro-ARM&#039;&#039;&#039;&#039;&#039; Projekt-Typ aus.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_1.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auf der nächsten Seite wird man darauf hingewiesen, dass das der entsprechende Projekt-Typ-Dialog ausgeführt wird. Hier kann man ein Häkchen bei &#039;&#039;&#039;&#039;&#039;Skip this page next time&#039;&#039;&#039;&#039;&#039; setzen und auf &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; klicken.&lt;br /&gt;
&lt;br /&gt;
Im nächsten Schritt wählen man das zuvor erstellt Verzeichnis unter &#039;&#039;&#039;&#039;&#039;Folder to create Project in&#039;&#039;&#039;&#039;&#039; aus, indem später alle Projekt gespeichert werden. Außerdem geben wir dem Projekt einen Namen (z.B. &#039;&#039;&#039;&#039;&#039;FirstProject&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_2.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danach muss man einen Compiler auswählen und bestimmen, welche Projekt-Konfigurationen erszeugt werden sollen. Unter &#039;&#039;&#039;&#039;&#039;Compiler&#039;&#039;&#039;&#039;&#039; wählt man &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039; und man kann das Häkchen bei &#039;&#039;&#039;&#039;&#039;Create &amp;quot;Release&amp;quot; configuration&#039;&#039;&#039;&#039;&#039; entfernen, da diese unnötig ist, die Debug-Konfiguration sollte eig. immer ausreichen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_3.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auf den folgenden Seite wird der Controller ausgewählt. Verwendet man ein STM32F4-Discovery Board müssen folgende Dinge gewählt werden: &#039;&#039;&#039;&#039;&#039;Cortex_M4 (F3xx - F4xx) -&amp;gt; STM32F4xx (Cortex M4 with FPU) -&amp;gt; STM32F407VG&#039;&#039;&#039;&#039;&#039;. Leider sind die Auswahl Möglichkeiten nicht ganz richtig, da auch die F3 Controller einen Cortex M4 Kern und eine FPU haben (Ist aber nicht so wichtig, ist nur eine formale Sache). Außerdem entfernt man das Häkchen bei &#039;&#039;&#039;&#039;&#039;Standard Peripherals Library&#039;&#039;&#039;&#039;&#039; (Wie man die Standard-Peripheral-Library einbindet und verwendet erkläre ich später). Man kann auch das Häkchen bei &#039;&#039;&#039;&#039;&#039;Create hex file for Realease target&#039;&#039;&#039;&#039;&#039; entfernen.&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;Stack Size&#039;&#039;&#039;&#039;&#039; und &#039;&#039;&#039;&#039;&#039;Heap Size&#039;&#039;&#039;&#039;&#039; wird die Größe von Stack und Heap festgelegt. Für eine erste Anwendung kann man die Einstellungen so lassen (Stack-Size: 0x0100 =&amp;gt; 256 Byte Stack und Heap-Size: 0x0000 =&amp;gt; kein Heap). Mit &#039;&#039;&#039;&#039;&#039;Finish&#039;&#039;&#039;&#039;&#039; ist der Projekt Dialog abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_4.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danach sollten sich zwei neue Fenster öffnen, um die Debug-Eigenschaften fest zu legen.&lt;br /&gt;
Verwendet man ein Discovery Board/ST-Link müssen die Einstellungen wie auf dem Bild gewählt werden. Über den Button &#039;&#039;&#039;&#039;&#039;Settings&#039;&#039;&#039;&#039;&#039; öffnet sich das zweite Fenster, falls sich dieses nicht schon von alleine öffnen sollte. Nach den Schließen der Fenster über &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; ist der Projekt Dialog beendet und ein neues Projekt steht zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_5_1.png|Debug Eigenschaften 1. Fenster]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_5_2.png|Debug Eigenschaften 2. Fenster]]&lt;br /&gt;
&lt;br /&gt;
===2. CMSIS-Library und Startup-Code hinzufügen===&lt;br /&gt;
Wenn man sich, nachdem man ein neues Projekt in der IDE erstellt hat, die bereits vorhandenen Dateien im Projekt ansieht, stellt man fest, das bereits ein Ordner &#039;&#039;&#039;&#039;&#039;cmsis&#039;&#039;&#039;&#039;&#039; existiert, der einige wichtige Include-Dateien der CMSIS-Library enthält. Allerdings sind das wirklich nur die wichtigsten Include-Dateien der CMSIS-Library und dazu noch, die aus einer älternen Version. Ich ziehe es deshalb vor die &amp;quot;Mini-CMSIS-Libraray&amp;quot; und die &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c/.h&#039;&#039;&#039;&#039;&#039; Dateien des Projektes durch aktuellere Versionen zu ersetzen. So ist später auch die Integration  von anderen Libraries, wie z.B. der CMSIS-DSP-Libarary einfacher.  &lt;br /&gt;
&lt;br /&gt;
Zunächst gehen man in das Projekt-Verzeichnis und löscht:&lt;br /&gt;
*Den Ordner &#039;&#039;&#039;&#039;&#039;cmsis&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Alle Dateien im Include Verzeichnis &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; im &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner&lt;br /&gt;
&lt;br /&gt;
Außerdem entfernt man auch alle gelöschten Dateien in der IDE aus dem Projekt mit &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Rechts Klick -&amp;gt; Remove file from project&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Es sollte folgende Verzeichnis Struktur überbleiben:&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_6.png|Überbleibende Dateien]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Jetzt müssen die gelöschten Dateien durch die aktuelleren ersetzt werden.&lt;br /&gt;
&lt;br /&gt;
*Dazu kopieren man den gesamten Ordner &#039;&#039;&#039;&#039;&#039;CMSIS&#039;&#039;&#039;&#039;&#039; aus dem CMSIS Download in das Projekt Verzeichnis.&lt;br /&gt;
&lt;br /&gt;
*Aus dem Standard-Peripheral-Library Download kopiert man von &#039;&#039;&#039;&#039;&#039;Libraries\CMSIS\Device\ST\STM32F4xx\Include&#039;&#039;&#039;&#039;&#039; alle Dateien in den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projekt Verzeichnisses&lt;br /&gt;
&lt;br /&gt;
*Aus der Standard-Peripheral-Library kopieren man ebenfalls von &#039;&#039;&#039;&#039;&#039;Libraries\CMSIS\Device\ST\STM32F4xx\Source\Templates&#039;&#039;&#039;&#039;&#039; die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; in den &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner des Projekts&lt;br /&gt;
&lt;br /&gt;
Anschließend müssen die neuen Dateien in der IDE dem Projekt hinzugefügt werden. Dazu benutzt man &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Rechts Klick -&amp;gt; Add files&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
*Aus dem &#039;&#039;&#039;&#039;&#039;CMSIS&#039;&#039;&#039;&#039;&#039; Ordner im Projekt Verzeichnis werden aus den Unterorder &#039;&#039;&#039;&#039;&#039;Include&#039;&#039;&#039;&#039;&#039; folgende Dateien dem Projekt hinzugefügt:&lt;br /&gt;
**arm_common_tables.h&lt;br /&gt;
**arm_const_structs.h&lt;br /&gt;
**arm_math.h&lt;br /&gt;
**core_cm4.h&lt;br /&gt;
**core_cm4_simd.h&lt;br /&gt;
**core_cmFunc.h&lt;br /&gt;
**core_cmInstr.h&lt;br /&gt;
*Alle Dateien aus den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projektes&lt;br /&gt;
*Die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; aus dem &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner&lt;br /&gt;
&lt;br /&gt;
So sollte die Struktur dann aussehen:&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_7.png|Anwenungs-Grundgerüst]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Da einige Dateien der Libraries später bearbeitet werden müssen und Schreibgeschützt sind, weise ich hier schonmal darauf hin, das der Schreibschutz in der IDE über &#039;&#039;&#039;&#039;&#039;Rechts Klick auf die Datei -&amp;gt; Properties -&amp;gt; Häkchen bei &amp;quot;File is read only&amp;quot; entfernen&#039;&#039;&#039;&#039;&#039; entfert werden kann.&lt;br /&gt;
&lt;br /&gt;
Damit die IDE die Header-Dateien der CMSIS Library auch finden kann, weil diese ja nicht im standard Include Ordner &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; liegen, muss unter &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Build Options -&amp;gt; Search Directories&#039;&#039;&#039;&#039;&#039; der Pfad &#039;&#039;&#039;&#039;&#039;CMSIS\Include&#039;&#039;&#039;&#039;&#039; hinzugefügt werden.&lt;br /&gt;
&lt;br /&gt;
Compiliert man jetzt das Projekt mit &#039;&#039;&#039;&#039;&#039;F7&#039;&#039;&#039;&#039;&#039; gibt es ein paar Fehler Meldungen, weil keine Controller-Reihe ausgewählt wurde. Ebenfalls unter &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Build Options -&amp;gt; Compiler Settings -&amp;gt; #defines&#039;&#039;&#039;&#039;&#039; wird der Define &#039;&#039;&#039;&#039;&#039;STM32F40_41xxx&#039;&#039;&#039;&#039;&#039; hinzugefügt.&lt;br /&gt;
&lt;br /&gt;
Beim erneuten Compilieren sollten sich nun keine neuen Fehler ergeben.&lt;br /&gt;
&lt;br /&gt;
===Das erste Programm===&lt;br /&gt;
Nachdem ein grundsätzliches &amp;quot;Gerüst&amp;quot; fertig ist, kann man den ersten Code schreiben.&lt;br /&gt;
main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC-&amp;gt;AHB1ENR |= RCC_AHB1ENR_GPIODEN;    //Takt für GPIO aktivieren&lt;br /&gt;
    GPIOD-&amp;gt;MODER |= GPIO_MODER_MODER15_0;   //GPIOD Pin15 als Ausgang&lt;br /&gt;
    GPIOD-&amp;gt;BSRRL |= GPIO_BSRR_BS_15;        //GPIOD Pin15 auf High ziehen&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039; wird dann der Debugger gestartet. Hat der Debugger das Projekt erfolgreich übertragen kann die Ausführung mit &#039;&#039;&#039;&#039;&#039;F5&#039;&#039;&#039;&#039;&#039; begonnen werden.&lt;br /&gt;
&lt;br /&gt;
==Libraries einbinden/verwenden==&lt;br /&gt;
===Einbinden der Standard-Peripheral-Library===&lt;br /&gt;
Um nicht immer die einzelnen Register, wie im ersten &amp;quot;bare-metal&amp;quot; Beispiel, aus dem Reference-Manual zu suchen und zu beschreiben, gibt es von ST die Standard Peripheral Library, die diese Aufgaben übernimmt und mit der sich die &amp;quot;normale/grundlegende&amp;quot; (Alles außer USB und Ethernet) Peripherie recht einfach steuern lässt. Um die Library zu verwenden erzeugt man wie oben beschrieben ein neues Grundgerüst und kopiert als erstes den Ordner &#039;&#039;&#039;&#039;&#039;Libraries\STM32F4xx_StdPeriph_Driver&#039;&#039;&#039;&#039;&#039; aus dem Standard-Peripheral-Library Download in das Projekt-Verzeichnis. Außerdem muss man die Datei &#039;&#039;&#039;&#039;&#039;Project\STM32F4xx_StdPeriph_Templates\stm32f4xx_conf.h&#039;&#039;&#039;&#039;&#039; ebenfalls aus dem Standard-Peripheral-Library Download in den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projektes kopieren. In der IDE fügt man den Include-Path &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\inc&#039;&#039;&#039;&#039;&#039; hinzufügen, wie bei der CMSIS-Library (s.o.).&lt;br /&gt;
Außerdem muss noch &#039;&#039;&#039;&#039;&#039;USE_STDPERIPH_DRIVER&#039;&#039;&#039;&#039;&#039; als Define in der IDE hinzugefügt werden (s.o.).&lt;br /&gt;
Danach fügt man die Source- und Include-Dateien aus dem Ordner &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\inc&#039;&#039;&#039;&#039;&#039; und &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\src&#039;&#039;&#039;&#039;&#039; dem Project mit &#039;&#039;&#039;&#039;&#039;&amp;lt;Project Name&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Add files&#039;&#039;&#039;&#039;&#039; hinzu, allerdings nur die, für welche auch der Controller die entsprechende Peripherie besitzt. Beim STM32F4-Discovery Board / STM32F407VG Controller dürfen also nicht folgende Dateien nicht mit hinzugefügt werden, weil diese Peripherie nur bei anderen Controller vorhanden ist:&lt;br /&gt;
&lt;br /&gt;
*stm32f4xx_dma2d.c/.h&lt;br /&gt;
*stm32f4xx_fmc.c/.h&lt;br /&gt;
*stm32f4xx_ltdc.c/.h&lt;br /&gt;
*stm32f4xx_sai.c/.h&lt;br /&gt;
&lt;br /&gt;
Daraus resultiert folgende Struktur:&lt;br /&gt;
&lt;br /&gt;
[[Datei:stdperiphlib_2.png|Header-Struktur]] [[Datei:stdperiphlib_1.png|Source-Struktur]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Anschließen kann die Standard-Peripheral-Library benutz werden.&lt;br /&gt;
main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);&lt;br /&gt;
&lt;br /&gt;
    GPIO_InitTypeDef GPIOD_InitStructure;&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Mode = GPIO_Mode_OUT;     //Als Ausgang&lt;br /&gt;
    GPIOD_InitStructure.GPIO_OType = GPIO_OType_PP;    //Push-Pull Betrieb&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Pin = GPIO_Pin_15;        //Pin 15 (STM32F4-Discovery: Blaue LED)&lt;br /&gt;
    GPIOD_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;  //Kein Pull-Up oder Pull-Down Widerstand aktiviert&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Speed = GPIO_Speed_25MHz; //25MHz Update-Rate&lt;br /&gt;
    GPIO_Init(GPIOD, &amp;amp;GPIOD_InitStructure);&lt;br /&gt;
&lt;br /&gt;
    GPIO_SetBits(GPIOD, GPIO_Pin_15);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Startup-Code, Linker-Script, Takt, FPU, Optimierung usw.==&lt;br /&gt;
===Startup-Code===&lt;br /&gt;
Em::Blocks fügt standardmäßig einen Startup-Code mit in das Projekt ein. Die wichtigsten Dinge die darin erledigt werden sind folgende:&lt;br /&gt;
&lt;br /&gt;
*Stack und Heap wird angelgt&lt;br /&gt;
*Die Vector-Table wird angelegt&lt;br /&gt;
*Ein Default Reset-Handler wird implementiert, dieser erledigt folgende aufgaben:&lt;br /&gt;
**Kopieren der definierten Daten aus dem Flash in den SRAM&lt;br /&gt;
**&#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; wird aufgerfen, wenn &#039;&#039;&#039;&#039;&#039;__NO_SYSTEM_INIT&#039;&#039;&#039;&#039;&#039; nicht definiert ist&lt;br /&gt;
**Sprung in die &#039;&#039;&#039;&#039;&#039;main()&#039;&#039;&#039;&#039;&#039; Funktion&lt;br /&gt;
*Allen anderen Interrupt-Handler wird eine Default-Funktion &#039;&#039;&#039;&#039;&#039;def_irq_handler&#039;&#039;&#039;&#039;&#039; mit einer &#039;&#039;&#039;&#039;&#039;while(1)&#039;&#039;&#039;&#039;&#039;-Schleife zugewiesen, falls kein anderer Interrupt-Handler existiert.&lt;br /&gt;
&lt;br /&gt;
Normalerweise muss am Startup-Code nichts verändert werden.&lt;br /&gt;
&lt;br /&gt;
===Linker-Script===&lt;br /&gt;
Em::Blocks stellt zwei fertige Linker-Scripts bereit, eins für die Ausführung des Programmes aus dem Flash (&#039;&#039;&#039;&#039;&#039;*_flash.ld&#039;&#039;&#039;&#039;&#039;), das andere für die Ausführung aus dem SRAM (&#039;&#039;&#039;&#039;&#039;*_sram.ld&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Normalerweise muss auch hier nichts geändert werden, es sei den Daten sollen in bestimmten Adressbereichen abgelegt werden (z.B. im Core-Coupled RAM), was ich später noch zum Tutorial hinzufüge.&lt;br /&gt;
&lt;br /&gt;
===Der Takt===&lt;br /&gt;
Jeder Controller oder Prozessor braucht einen Takt, indem er die einzelnen Maschinen-Befehle abarbeiten kann.&lt;br /&gt;
Bei den STM32 Mikrocontrollern kann dieser Takt aus verschiedenen Quellen kommen:&lt;br /&gt;
&lt;br /&gt;
1. High Speed Internal Oszillator (HSI)&lt;br /&gt;
&lt;br /&gt;
2. High Speed External Oszillator (HSE)&lt;br /&gt;
&lt;br /&gt;
3. Low Speed Internal Oszillator (LSI)&lt;br /&gt;
&lt;br /&gt;
4. Low Speed External Oszillator (LSE)&lt;br /&gt;
&lt;br /&gt;
5. Phase-Locked Loop (PLL) (generiert den Takt aus den ersten vier Taktquellen durch Teiler und Faktoren)&lt;br /&gt;
&lt;br /&gt;
Nach einem Reset wird der Controller aus der HSI Taktquelle versorgt (16MHz beim STM32F407VG). Um die voll Performance des Controllers zu erreichen muss die PLL verwendet werden, welche den Takt durch geschickte Teiler und Faktoren vervielfältigt, sodass am Ende der Controller mit der maximalen Taktfrequenz läuft. Die notwendige Initialisierung der PLL findet in der Funktion &#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; statt. Die PLL erzeugt zunächst einen Basistakt:&lt;br /&gt;
&lt;br /&gt;
PLL_VCO = (F_HSE / PLL_M) * PLL_N&lt;br /&gt;
&lt;br /&gt;
Aus diesem Takt wird dann der Takt für den Controller-Kern abgeleitet:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = PLL_VCO / PLL_P&lt;br /&gt;
&lt;br /&gt;
Und der Takt für SDIO / USB / RNG (48MHz):&lt;br /&gt;
&lt;br /&gt;
48MHz = PLL_VCO / PLL_Q&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Durch weiter Teiler werden, die Takte für die einzelnen Busse erzeugt, da diese nicht alle beliebig schnell betrieben werden dürfen.&lt;br /&gt;
&lt;br /&gt;
Genaue Angaben findet man zu dem jeweiligen Clock-System des Controllers im Reference Manual.&lt;br /&gt;
&lt;br /&gt;
Ein Blick in den &amp;quot;Kommentar-Header&amp;quot; verrät, dass von einem externen (HSE) Oszillator von 25MHz ausgegangen wird, der die PLL versorgen soll.&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((25MHz / PLL_M(25)) * PLL_N(336)) / PLL_P(2) = 168MHz&lt;br /&gt;
&lt;br /&gt;
Allerdings stimmt diese Rechnung natürlich nur, wenn wirklich ein 25MHz Quarz am Controller angeschlossen ist. Auf dem STM32F4-Discovery Board befindet sich aber nur ein 8MHz Quarz. Demnach gilt:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((8MHz / PLL_M(25)) * PLL_N(336)) / PLL_P(2) = 53.76MHz&lt;br /&gt;
&lt;br /&gt;
Der Controller läuft also nur mit 53.76MHz, wenn wie ober beschrieben ein Projekt erstellt wird. Allerdings kann dieses Problem durch ändern von den betroffen Defines behoben werden:&lt;br /&gt;
 &lt;br /&gt;
*Dazu geht man in die &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; Datei und passt zur Vollständigkeit erstmal die zum Controller passende Tabelle im &amp;quot;Kommentar-Header&amp;quot; an (Z.57f):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      HSE Frequency(Hz)                      | 8000000&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      PLL_M                                  | 8&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Danach passt man den PPL_M Define (Z.254) an:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/************************* PLL Parameters *************************************/&lt;br /&gt;
/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */&lt;br /&gt;
#define PLL_M      8&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Außerdem muss man den HSE_VALUE Define in der &#039;&#039;&#039;&#039;&#039;inc/stm32f4xx.h&#039;&#039;&#039;&#039;&#039; angepasst werden (Z.122):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#if !defined  (HSE_VALUE)&lt;br /&gt;
  #define HSE_VALUE    ((uint32_t)8000000) /*!&amp;lt; Value of the External oscillator in Hz */&lt;br /&gt;
&lt;br /&gt;
#endif /* HSE_VALUE */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine neue Berechnung zeigt:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((8MHz / PLL_M(8)) * PLL_N(336)) / PLL_P(2) = 168MHz&lt;br /&gt;
&lt;br /&gt;
Jetzt läuft der Controller mit maximaler Geschwindigkeit.&lt;br /&gt;
&lt;br /&gt;
Die Theorie wird durch folgendes Programm verifiziert. Der geviertelte System-Takt SYSCLK wir am Pin PC9 ausgegeben. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);&lt;br /&gt;
&lt;br /&gt;
    GPIO_InitTypeDef GPIOC_InitStructure;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Mode = GPIO_Mode_AF;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_OType = GPIO_OType_PP;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Pin = GPIO_Pin_9;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;&lt;br /&gt;
    GPIO_Init(GPIOC, &amp;amp;GPIOC_InitStructure);&lt;br /&gt;
&lt;br /&gt;
    RCC_MCO2Config(RCC_MCO2Source_SYSCLK, RCC_MCO2Div_4);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Die FPU===&lt;br /&gt;
====Allgemeines====&lt;br /&gt;
Damit die FPU richtig verwendet wird, müssen normalerweise zwei Bedingungen erfüllt sein:&lt;br /&gt;
&lt;br /&gt;
1. Der Controller muss in der Initialisierung-Funktion &#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; in &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; die FPU Hardware-seitig aktivieren&lt;br /&gt;
&lt;br /&gt;
2. Damit die FPU auch was zu tuen bekommt, müssen vom Compiler FPU-Instructions erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
Die Em::Blocks IDE verwendet standardmäßig die FPU, wenn eine Vorhanden ist. Hier wird die FPU Hardware-seitig aktiviert (&#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; Z.341):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* FPU settings ------------------------------------------------------------*/&lt;br /&gt;
  #if (__FPU_PRESENT == 1) &amp;amp;&amp;amp; (__FPU_USED == 1)&lt;br /&gt;
    SCB-&amp;gt;CPACR |= ((3UL &amp;lt;&amp;lt; 10*2)|(3UL &amp;lt;&amp;lt; 11*2));  /* set CP10 and CP11 Full Access */&lt;br /&gt;
  #endif&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
__FPU_PRESENT wird in der &#039;&#039;&#039;&#039;&#039;stm32f4xx.h&#039;&#039;&#039;&#039;&#039; definiert.&lt;br /&gt;
__FPU_USED wird von der IDE übernommen (siehe Build-Log): &#039;&#039;&#039;&#039;&#039;-D__FPU_USED&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Außerdem wird der Compiler von der IDE standardmäßig mit dem Argument &#039;&#039;&#039;&#039;&#039;-mfloat-abi=hard&#039;&#039;&#039;&#039;&#039; aufgerufen, wodurch FPU-Instructions erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
====FPU abschalten====&lt;br /&gt;
Um die FPU ab zu schalten (Mir würde jetzt nur Strom sparen als Grund einfallen) geht man wie folgt vor:&lt;br /&gt;
&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick Build options -&amp;gt; Device -&amp;gt; Policy&#039;&#039;&#039;&#039;&#039; wählt man &#039;&#039;&#039;&#039;&#039;Use target settings&#039;&#039;&#039;&#039;&#039; und über nimmt die Einstellungen, die vorher dort eingetragen waren, allerdings lässt man das Feld &#039;&#039;&#039;&#039;&#039;FP-hardware&#039;&#039;&#039;&#039;&#039; frei.&lt;br /&gt;
&lt;br /&gt;
[[Datei:fpu_1.png|FPU Abschalten Schritt 1]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;Compiler Settings -&amp;gt; Policy&#039;&#039;&#039;&#039;&#039; wählt man dann &#039;&#039;&#039;&#039;&#039;Use target options only&#039;&#039;&#039;&#039;&#039;. Dann kann man unter &#039;&#039;&#039;&#039;&#039;Categories&#039;&#039;&#039;&#039;&#039; die Option &#039;&#039;&#039;&#039;&#039;ARM FPU architecture&#039;&#039;&#039;&#039;&#039; auswählen. Dort stehen dann drei Möglichkeiten für die FPU zur Verfügung:&lt;br /&gt;
&lt;br /&gt;
1. Software-FPU-Library für Gleitkomma-Berechnung verwenden - Keine FPU-Instructions werden generiert (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=soft&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
2. Eine Mischung aus Software- und Hardware-FPU wird verwendet (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=softfp&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
3. Hardware-FPU wird für Gleitkomma-Berechnungen verwendet (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=hard&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
[[Datei:fpu_2.png|FPU Abschalten Schritt 2]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Um die FPU ab zu schalten wählt man natürlich die erste Möglichkeit.&lt;br /&gt;
Bei der 2. und 3. Möglichkeit fügt die IDE auch den Define &#039;&#039;&#039;&#039;&#039;__FPU_USED&#039;&#039;&#039;&#039;&#039; hinzu. Bei Der ersten Möglichkeit nicht. Der Code muss also nicht verändert / auskommentiert werden.&lt;br /&gt;
&lt;br /&gt;
Um die FPU wieder zu aktivieren müssen alle Schritte wieder rückgängig gemacht werden.&lt;br /&gt;
&lt;br /&gt;
Am besten ist es einfach mal alle Möglichkeiten im Einzelschritt durch zu probieren. Dann stellt man schnell fest, ob die FPU aktiviert wir oder nicht. Ein Blick in den erweiterten &#039;&#039;&#039;&#039;&#039;Build-Log&#039;&#039;&#039;&#039;&#039; gibt auch schnell Aufschluss darüber, wie der Compiler aufgerufen wird (siehe Kapitel [http://www.mikrocontroller.net/articles/STM32_-_Einstieg_mit_Em::Blocks#Compilieren Compilieren]).&lt;br /&gt;
&lt;br /&gt;
====Test Programm für die FPU====&lt;br /&gt;
Hier ein kleines Testprogramm, dass misst wie viele Taktzyklen für eine Gleitkomma-Multiplikation gebraucht werden. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define CORE_SysTickEn()    (*((u32*)0xE0001000)) = 0x40000001&lt;br /&gt;
#define CORE_SysTickDis()   (*((u32*)0xE0001000)) = 0x40000000&lt;br /&gt;
#define CORE_GetSysTick()   (*((u32*)0xE0001004))&lt;br /&gt;
&lt;br /&gt;
uint32_t t1, t2, dt;&lt;br /&gt;
float x, y, z;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    x = 53.64f;&lt;br /&gt;
    y = 0.27f;&lt;br /&gt;
&lt;br /&gt;
    CORE_SysTickEn();&lt;br /&gt;
    t1 = CORE_GetSysTick();&lt;br /&gt;
&lt;br /&gt;
    z = x * y;&lt;br /&gt;
&lt;br /&gt;
    t2 = CORE_GetSysTick();&lt;br /&gt;
    CORE_SysTickDis();&lt;br /&gt;
&lt;br /&gt;
    dt = (t2 - t1) - 9; //9 Takt-Zyklen werden für die Messung gebraucht &lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Compiler-Optimierung===&lt;br /&gt;
Standardmäßig verwendet Em::Blocks keine Optimierung. Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; Categories&#039;&#039;&#039;&#039;&#039; kann zwischen verschieden Optimierungen ausgewählt werden.&lt;br /&gt;
&lt;br /&gt;
==Booten aus dem SRAM==&lt;br /&gt;
STM32 Controller haben die Möglichkeit Code aus dem Flash als auch aus dem SRAM auszuführen. Um eine Anwenung per Debugger in des SRAM zu laden sind nur wenige Schritte erforderlich:&lt;br /&gt;
&lt;br /&gt;
*Um das Linkerscript für den SRAM zu verwenden geht man zu: &#039;&#039;&#039;&#039;&#039;Build options... -&amp;gt; Device&#039;&#039;&#039;&#039;&#039; dort wählt man unter &#039;&#039;&#039;&#039;&#039;Policy&#039;&#039;&#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;Use target settings&#039;&#039;&#039;&#039;&#039; aus und übernimmt die vorherigen Einstellungen, nur unter &#039;&#039;&#039;&#039;&#039;Linker script*&#039;&#039;&#039;&#039;&#039; gibt man &#039;&#039;&#039;&#039;&#039;.\stm32f407vg_sram.ld&#039;&#039;&#039;&#039;&#039; an&lt;br /&gt;
&lt;br /&gt;
*Dann muss man noch unter &#039;&#039;&#039;&#039;&#039;Debug -&amp;gt; Interfaces -&amp;gt; Settings&#039;&#039;&#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;Vector table start&#039;&#039;&#039;&#039;&#039; auf 0x20000000 ändern und &#039;&#039;&#039;&#039;&#039;Execute from RAM&#039;&#039;&#039;&#039;&#039; auswählen.&lt;br /&gt;
&lt;br /&gt;
Anschließend kann man die Anwendung ganz normal debuggen. Nach einem Reset muss die Anwenung erneut mit dem Debugger gestartet werden.&lt;br /&gt;
&lt;br /&gt;
=Fortsetzung folgt..=&lt;br /&gt;
Kritik, Wünsche usw. sind gerne erwünscht, am besten hier in den Thread posten: [http://www.mikrocontroller.net/topic/323750 Neues STM32 Tutorial]&lt;br /&gt;
&lt;br /&gt;
[[Category:ARM]]&lt;br /&gt;
[[Category:STM32]]&lt;/div&gt;</summary>
		<author><name>Avrprogger</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=STM32_-_Einstieg_mit_Em::Blocks&amp;diff=81520</id>
		<title>STM32 - Einstieg mit Em::Blocks</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=STM32_-_Einstieg_mit_Em::Blocks&amp;diff=81520"/>
		<updated>2014-02-10T21:20:38Z</updated>

		<summary type="html">&lt;p&gt;Avrprogger: dfg&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In diesem Tutorial werde ich versuchen, möglichst einfach, die ersten Schritte zur Entwicklung von STM32 Anwenungen mit der Em::Blocks IDE zu erklären. Hier soll nicht so stark auf die einzelnen Peripherie-Module der Controller eingegangen werden, sondern mehr auf die IDE und die verschieden Libraries, wie die CMSIS Library, die DSP-Library, die Standard-Peripheral-Library, die USB-Library und vllt. über Ethernet. Ich denke ein Kapitel zu FreeRTOS wird es auch geben. Auserdem steht im Vordergrund Sachen wie z.B. booten aus dem SRAM, In-Application-Programming, FPU, Core-Coupled-RAM usw. Mal sehn wie weit ich komme ;)&lt;br /&gt;
&lt;br /&gt;
==Die Entwicklungsumgebung==&lt;br /&gt;
===Hardware===&lt;br /&gt;
Zum testen der Anwendungen, benutze ich das STM32F4-Discovery Board, welches einen Debugger, Peripherie und natürlich einen STM32 Controller (STM32F407VGT6) enthält. Deshalb sind alle Beispiele hier für den STM32F407VG Controller ausgelegt, können aber meisten 1:1 auf andere Controller portiert werden. Ich werde auch möglichsts keine STM32F4-Discovery Board spezifischen Libraries verwenden, damit der Portierungs-Vorgang möglichsts einfach bleibt.&lt;br /&gt;
&lt;br /&gt;
===Software===&lt;br /&gt;
In diesem Tutorial verwende ich [http://www.emblocks.org/ Em::Blocks] als IDE. Em::Blocks ist eine kostenlose, uneingeschränkte IDE, die alle STM32 Mikrcontroller unterstützt und sehr einfach zu bedienen ist.&lt;br /&gt;
nach dem Download kann die IDE per Dialog, sehr einfach, installiert werden. Als Compiler beinhaltet Em::Blocks den &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
Die IDE unterstützt zurzeit den ST-Link, den J-Link und es gibt eine Generic-Vorlage, durch welche andere Debugger konfiguriert werden können.&lt;br /&gt;
&lt;br /&gt;
Außerdem muss noch der passende Treiber für den Debugger installiert werden. Verwendet man ein Discovery-Board muss der [http://www.st.com/web/catalog/tools/FM146/CL1984/SC724/SS1677/PF251168 ST-Link/V2]-Treiber heruntergeladen und installiert werden. (Die Installation muss evtl. als Administrator ausgeführt werden, da sonst die Installation unvollständig wird.) Nach der Installation des Treibers kann man den Debugger über die entsprechende USB Schnittstelle an den PC anschließen und es sollte die Meldung von Windows kommen, dass der richtige Treiber gefunden wurde.&lt;br /&gt;
&lt;br /&gt;
===Libraries===&lt;br /&gt;
Zum programmieren benötigt man noch die [http://www.arm.com/products/processors/cortex-m/cortex-microcontroller-software-interface-standard.php CMSIS] und die Standard-Peripheral-Library (z.B. für die F4 Controller [http://www.st.com/stonline/stappl/productcatalog/app?page=partNumberSearchPage&amp;amp;levelid=SS1577&amp;amp;parentid=1743&amp;amp;resourcetype=SW Standard-Peripheral-Library-F4]), die man am besten in einen Ordner (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\STM32&#039;&#039;&#039;&#039;&#039;) entpackt&lt;br /&gt;
&lt;br /&gt;
==Basis-Wissen zur IDE==&lt;br /&gt;
Einige Grundfunktionalitäten der IDE:&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von Dateien zum Projekt===&lt;br /&gt;
Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf &amp;lt;ProjektName&amp;gt; -&amp;gt; Add files...&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Enfernen von Dateien aus dem Projekt===&lt;br /&gt;
Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf die Datei / mehrere Dateien auswählen -&amp;gt; Remove file from project&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
Die Dateien werden lediglich aus dem Projekt entfernt und nicht von der Festplatte gelöscht.&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von Include-Pfaden===&lt;br /&gt;
Sofern die Include-Datei(en) nicht im standard Include-Ordner &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; des Projektes liegen, muss man den Pfad zum Projekt hinzufügen, damit der Compiler die Include-Dateien später auch finden kann. Man geht wie folgt vor: Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf &amp;lt;ProjektName&amp;gt; -&amp;gt; Build options... -&amp;gt; Search Directories -&amp;gt; Add&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Compilieren===&lt;br /&gt;
Entweder über das &#039;&#039;&#039;&#039;&#039;Build&#039;&#039;&#039;&#039;&#039; Menü oder über &#039;&#039;&#039;&#039;&#039;F7&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Um eine genau Ausgabe des Compiler-Aufrufes mit allen Argumenten zu bekommen, geht man im &#039;&#039;&#039;&#039;&#039;Settings&#039;&#039;&#039;&#039;&#039; Menü auf &#039;&#039;&#039;&#039;&#039;Tools...&#039;&#039;&#039;&#039;&#039; und dann auf &#039;&#039;&#039;&#039;&#039;Toolchain executables&#039;&#039;&#039;&#039;&#039;. Ganz unten, unter &#039;&#039;&#039;&#039;&#039;Logging&#039;&#039;&#039;&#039;&#039; kann man dann &#039;&#039;&#039;&#039;&#039;Full command line&#039;&#039;&#039;&#039;&#039; auswählen.&lt;br /&gt;
&lt;br /&gt;
===Debuggen===&lt;br /&gt;
*Als erstes den Debugger starten über das &#039;&#039;&#039;&#039;&#039;Debug&#039;&#039;&#039;&#039;&#039; Menü und &#039;&#039;&#039;&#039;&#039;Start/stop Debug Session&#039;&#039;&#039;&#039;&#039; oder über &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
*Danach läuft die Anwendung auf dem Controller und warten im &#039;&#039;&#039;&#039;&#039;Reset_Handler&#039;&#039;&#039;&#039;&#039; auf Einzelschritt- bzw. Run- Befehle (&#039;&#039;&#039;&#039;&#039;F5, F10, F11&#039;&#039;&#039;&#039;&#039; usw..(siehe &#039;&#039;&#039;&#039;&#039;Debug-Menü&#039;&#039;&#039;&#039;&#039; für alle Möglichkeiten))&lt;br /&gt;
&lt;br /&gt;
*Mit &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039; wird die Debug-Session auch wieder beendet&lt;br /&gt;
&lt;br /&gt;
*Unter &#039;&#039;&#039;&#039;&#039;Debug -&amp;gt; Interfaces -&amp;gt; Target settings&#039;&#039;&#039;&#039;&#039; können Eigenschaften, wie z.B &#039;&#039;&#039;&#039;&#039;Run to main()&#039;&#039;&#039;&#039;&#039; aktiviert werden.&lt;br /&gt;
&lt;br /&gt;
===Projekt als Template abspeichern===&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;File -&amp;gt; Save project as template...&#039;&#039;&#039;&#039;&#039;. Das Template erscheint dann im Projekt-Dialog unter &#039;&#039;&#039;&#039;&#039;User templates&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Das erste Projekt erstellen==&lt;br /&gt;
Hier erkläre ich, wie man am Besten (aus meiner Sicht), ein neues Projekt von Grund auf erstellt, sodass man hinterher, den Controller-Kern über die CMSIS-Library und die Peripherie über die Register steuern kann.&lt;br /&gt;
&lt;br /&gt;
===1. Projekt mit der IDE erstellen===&lt;br /&gt;
Nach der Installation der oben beschriebenen Komponenten erstellt man am besten ein Verzeichnis (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\EmBlocks&#039;&#039;&#039;&#039;&#039;), indem später alle Projekte gespeichert werden. Für Libraries kann man auch noch ein Verzeichnis (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\STM32&#039;&#039;&#039;&#039;&#039;) erstellen, wo alle Libraries gespeichert werden, die man für die Projekt brauchen.&lt;br /&gt;
&lt;br /&gt;
Als nächstes starten man EmBlocks. Bei dem ersten Start öffnet sich ein Fenster, wo verschiedene Compiler angezeigt werden, die Em::Blocks findet. Dort wählt man den &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039; aus und klickt &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039;. Nun sollte sich das Hauptfenster von Em::Blocks öffnen. Über &#039;&#039;&#039;&#039;&#039;Create a new Project&#039;&#039;&#039;&#039;&#039; oder &#039;&#039;&#039;&#039;&#039;File -&amp;gt; New -&amp;gt; Project&#039;&#039;&#039;&#039;&#039; ruft man den Projekt-Dialog auf und kann ein neues Projekt erzeugen.&lt;br /&gt;
&lt;br /&gt;
Auf der Ersten Seite wählen man den &#039;&#039;&#039;&#039;&#039;STmicro-ARM&#039;&#039;&#039;&#039;&#039; Projekt-Typ aus.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_1.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auf der nächsten Seite wird man darauf hingewiesen, dass das der entsprechende Projekt-Typ-Dialog ausgeführt wird. Hier kann man ein Häkchen bei &#039;&#039;&#039;&#039;&#039;Skip this page next time&#039;&#039;&#039;&#039;&#039; setzen und auf &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; klicken.&lt;br /&gt;
&lt;br /&gt;
Im nächsten Schritt wählen man das zuvor erstellt Verzeichnis unter &#039;&#039;&#039;&#039;&#039;Folder to create Project in&#039;&#039;&#039;&#039;&#039; aus, indem später alle Projekt gespeichert werden. Außerdem geben wir dem Projekt einen Namen (z.B. &#039;&#039;&#039;&#039;&#039;FirstProject&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_2.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danach muss man einen Compiler auswählen und bestimmen, welche Projekt-Konfigurationen erszeugt werden sollen. Unter &#039;&#039;&#039;&#039;&#039;Compiler&#039;&#039;&#039;&#039;&#039; wählt man &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039; und man kann das Häkchen bei &#039;&#039;&#039;&#039;&#039;Create &amp;quot;Release&amp;quot; configuration&#039;&#039;&#039;&#039;&#039; entfernen, da diese unnötig ist, die Debug-Konfiguration sollte eig. immer ausreichen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_3.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auf den folgenden Seite wird der Controller ausgewählt. Verwendet man ein STM32F4-Discovery Board müssen folgende Dinge gewählt werden: &#039;&#039;&#039;&#039;&#039;Cortex_M4 (F3xx - F4xx) -&amp;gt; STM32F4xx (Cortex M4 with FPU) -&amp;gt; STM32F407VG&#039;&#039;&#039;&#039;&#039;. Leider sind die Auswahl Möglichkeiten nicht ganz richtig, da auch die F3 Controller einen Cortex M4 Kern und eine FPU haben (Ist aber nicht so wichtig, ist nur eine formale Sache). Außerdem entfernt man das Häkchen bei &#039;&#039;&#039;&#039;&#039;Standard Peripherals Library&#039;&#039;&#039;&#039;&#039; (Wie man die Standard-Peripheral-Library einbindet und verwendet erkläre ich später). Man kann auch das Häkchen bei &#039;&#039;&#039;&#039;&#039;Create hex file for Realease target&#039;&#039;&#039;&#039;&#039; entfernen.&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;Stack Size&#039;&#039;&#039;&#039;&#039; und &#039;&#039;&#039;&#039;&#039;Heap Size&#039;&#039;&#039;&#039;&#039; wird die Größe von Stack und Heap festgelegt. Für eine erste Anwendung kann man die Einstellungen so lassen (Stack-Size: 0x0100 =&amp;gt; 256 Byte Stack und Heap-Size: 0x0000 =&amp;gt; kein Heap). Mit &#039;&#039;&#039;&#039;&#039;Finish&#039;&#039;&#039;&#039;&#039; ist der Projekt Dialog abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_4.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danach sollten sich zwei neue Fenster öffnen, um die Debug-Eigenschaften fest zu legen.&lt;br /&gt;
Verwendet man ein Discovery Board/ST-Link müssen die Einstellungen wie auf dem Bild gewählt werden. Über den Button &#039;&#039;&#039;&#039;&#039;Settings&#039;&#039;&#039;&#039;&#039; öffnet sich das zweite Fenster, falls sich dieses nicht schon von alleine öffnen sollte. Nach den Schließen der Fenster über &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; ist der Projekt Dialog beendet und ein neues Projekt steht zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_5_1.png|Debug Eigenschaften 1. Fenster]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_5_2.png|Debug Eigenschaften 2. Fenster]]&lt;br /&gt;
&lt;br /&gt;
===2. CMSIS-Library und Startup-Code hinzufügen===&lt;br /&gt;
Wenn man sich, nachdem man ein neues Projekt in der IDE erstellt hat, die bereits vorhandenen Dateien im Projekt ansieht, stellt man fest, das bereits ein Ordner &#039;&#039;&#039;&#039;&#039;cmsis&#039;&#039;&#039;&#039;&#039; existiert, der einige wichtige Include-Dateien der CMSIS-Library enthält. Allerdings sind das wirklich nur die wichtigsten Include-Dateien der CMSIS-Library und dazu noch, die aus einer älternen Version. Ich ziehe es deshalb vor die &amp;quot;Mini-CMSIS-Libraray&amp;quot; und die &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c/.h&#039;&#039;&#039;&#039;&#039; Dateien des Projektes durch aktuellere Versionen zu ersetzen. So ist später auch die Integration  von anderen Libraries, wie z.B. der CMSIS-DSP-Libarary einfacher.  &lt;br /&gt;
&lt;br /&gt;
Zunächst gehen man in das Projekt-Verzeichnis und löscht:&lt;br /&gt;
*Den Ordner &#039;&#039;&#039;&#039;&#039;cmsis&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Alle Dateien im Include Verzeichnis &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; im &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner&lt;br /&gt;
&lt;br /&gt;
Außerdem entfernt man auch alle gelöschten Dateien in der IDE aus dem Projekt mit &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Rechts Klick -&amp;gt; Remove file from project&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Es sollte folgende Verzeichnis Struktur überbleiben:&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_6.png|Überbleibende Dateien]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Jetzt müssen die gelöschten Dateien durch die aktuelleren ersetzt werden.&lt;br /&gt;
&lt;br /&gt;
*Dazu kopieren man den gesamten Ordner &#039;&#039;&#039;&#039;&#039;CMSIS&#039;&#039;&#039;&#039;&#039; aus dem CMSIS Download in das Projekt Verzeichnis.&lt;br /&gt;
&lt;br /&gt;
*Aus dem Standard-Peripheral-Library Download kopiert man von &#039;&#039;&#039;&#039;&#039;Libraries\CMSIS\Device\ST\STM32F4xx\Include&#039;&#039;&#039;&#039;&#039; alle Dateien in den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projekt Verzeichnisses&lt;br /&gt;
&lt;br /&gt;
*Aus der Standard-Peripheral-Library kopieren man ebenfalls von &#039;&#039;&#039;&#039;&#039;Libraries\CMSIS\Device\ST\STM32F4xx\Source\Templates&#039;&#039;&#039;&#039;&#039; die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; in den &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner des Projekts&lt;br /&gt;
&lt;br /&gt;
Anschließend müssen die neuen Dateien in der IDE dem Projekt hinzugefügt werden. Dazu benutzt man &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Rechts Klick -&amp;gt; Add files&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
*Aus dem &#039;&#039;&#039;&#039;&#039;CMSIS&#039;&#039;&#039;&#039;&#039; Ordner im Projekt Verzeichnis werden aus den Unterorder &#039;&#039;&#039;&#039;&#039;Include&#039;&#039;&#039;&#039;&#039; folgende Dateien dem Projekt hinzugefügt:&lt;br /&gt;
**arm_common_tables.h&lt;br /&gt;
**arm_const_structs.h&lt;br /&gt;
**arm_math.h&lt;br /&gt;
**core_cm4.h&lt;br /&gt;
**core_cm4_simd.h&lt;br /&gt;
**core_cmFunc.h&lt;br /&gt;
**core_cmInstr.h&lt;br /&gt;
*Alle Dateien aus den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projektes&lt;br /&gt;
*Die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; aus dem &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner&lt;br /&gt;
&lt;br /&gt;
So sollte die Struktur dann aussehen:&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_7.png|Anwenungs-Grundgerüst]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Da einige Dateien der Libraries später bearbeitet werden müssen und Schreibgeschützt sind, weise ich hier schonmal darauf hin, das der Schreibschutz in der IDE über &#039;&#039;&#039;&#039;&#039;Rechts Klick auf die Datei -&amp;gt; Properties -&amp;gt; Häkchen bei &amp;quot;File is read only&amp;quot; entfernen&#039;&#039;&#039;&#039;&#039; entfert werden kann.&lt;br /&gt;
&lt;br /&gt;
Damit die IDE die Header-Dateien der CMSIS Library auch finden kann, weil diese ja nicht im standard Include Ordner &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; liegen, muss unter &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Build Options -&amp;gt; Search Directories&#039;&#039;&#039;&#039;&#039; der Pfad &#039;&#039;&#039;&#039;&#039;CMSIS\Include&#039;&#039;&#039;&#039;&#039; hinzugefügt werden.&lt;br /&gt;
&lt;br /&gt;
Compiliert man jetzt das Projekt mit &#039;&#039;&#039;&#039;&#039;F7&#039;&#039;&#039;&#039;&#039; gibt es ein paar Fehler Meldungen, weil keine Controller-Reihe ausgewählt wurde. Ebenfalls unter &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Build Options -&amp;gt; Compiler Settings -&amp;gt; #defines&#039;&#039;&#039;&#039;&#039; wird der Define &#039;&#039;&#039;&#039;&#039;STM32F40_41xxx&#039;&#039;&#039;&#039;&#039; hinzugefügt.&lt;br /&gt;
&lt;br /&gt;
Beim erneuten Compilieren sollten sich nun keine neuen Fehler ergeben.&lt;br /&gt;
&lt;br /&gt;
===Das erste Programm===&lt;br /&gt;
Nachdem ein grundsätzliches &amp;quot;Gerüst&amp;quot; fertig ist, kann man den ersten Code schreiben.&lt;br /&gt;
main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC-&amp;gt;AHB1ENR |= RCC_AHB1ENR_GPIODEN;    //Takt für GPIO aktivieren&lt;br /&gt;
    GPIOD-&amp;gt;MODER |= GPIO_MODER_MODER15_0;   //GPIOD Pin15 als Ausgang&lt;br /&gt;
    GPIOD-&amp;gt;BSRRL |= GPIO_BSRR_BS_15;        //GPIOD Pin15 auf High ziehen&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039; wird dann der Debugger gestartet. Hat der Debugger das Projekt erfolgreich übertragen kann die Ausführung mit &#039;&#039;&#039;&#039;&#039;F5&#039;&#039;&#039;&#039;&#039; begonnen werden.&lt;br /&gt;
&lt;br /&gt;
==Libraries einbinden/verwenden==&lt;br /&gt;
===Einbinden der Standard-Peripheral-Library===&lt;br /&gt;
Um nicht immer die einzelnen Register, wie im ersten &amp;quot;bare-metal&amp;quot; Beispiel, aus dem Reference-Manual zu suchen und zu beschreiben, gibt es von ST die Standard Peripheral Library, die diese Aufgaben übernimmt und mit der sich die &amp;quot;normale/grundlegende&amp;quot; (Alles außer USB und Ethernet) Peripherie recht einfach steuern lässt. Um die Library zu verwenden erzeugt man wie oben beschrieben ein neues Grundgerüst und kopiert als erstes den Ordner &#039;&#039;&#039;&#039;&#039;Libraries\STM32F4xx_StdPeriph_Driver&#039;&#039;&#039;&#039;&#039; aus dem Standard-Peripheral-Library Download in das Projekt-Verzeichnis. Außerdem muss man die Datei &#039;&#039;&#039;&#039;&#039;Project\STM32F4xx_StdPeriph_Templates\stm32f4xx_conf.h&#039;&#039;&#039;&#039;&#039; ebenfalls aus dem Standard-Peripheral-Library Download in den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projektes kopieren. In der IDE fügt man den Include-Path &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\inc&#039;&#039;&#039;&#039;&#039; hinzufügen, wie bei der CMSIS-Library (s.o.).&lt;br /&gt;
Außerdem muss noch &#039;&#039;&#039;&#039;&#039;USE_STDPERIPH_DRIVER&#039;&#039;&#039;&#039;&#039; als Define in der IDE hinzugefügt werden (s.o.).&lt;br /&gt;
Danach fügt man die Source- und Include-Dateien aus dem Ordner &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\inc&#039;&#039;&#039;&#039;&#039; und &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\src&#039;&#039;&#039;&#039;&#039; dem Project mit &#039;&#039;&#039;&#039;&#039;&amp;lt;Project Name&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Add files&#039;&#039;&#039;&#039;&#039; hinzu, allerdings nur die, für welche auch der Controller die entsprechende Peripherie besitzt. Beim STM32F4-Discovery Board / STM32F407VG Controller dürfen also nicht folgende Dateien nicht mit hinzugefügt werden, weil diese Peripherie nur bei anderen Controller vorhanden ist:&lt;br /&gt;
&lt;br /&gt;
*stm32f4xx_dma2d.c/.h&lt;br /&gt;
*stm32f4xx_fmc.c/.h&lt;br /&gt;
*stm32f4xx_ltdc.c/.h&lt;br /&gt;
*stm32f4xx_sai.c/.h&lt;br /&gt;
&lt;br /&gt;
Daraus resultiert folgende Struktur:&lt;br /&gt;
&lt;br /&gt;
[[Datei:stdperiphlib_2.png|Header-Struktur]] [[Datei:stdperiphlib_1.png|Source-Struktur]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Anschließen kann die Standard-Peripheral-Library benutz werden.&lt;br /&gt;
main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);&lt;br /&gt;
&lt;br /&gt;
    GPIO_InitTypeDef GPIOD_InitStructure;&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Mode = GPIO_Mode_OUT;     //Als Ausgang&lt;br /&gt;
    GPIOD_InitStructure.GPIO_OType = GPIO_OType_PP;    //Push-Pull Betrieb&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Pin = GPIO_Pin_15;        //Pin 15 (STM32F4-Discovery: Blaue LED)&lt;br /&gt;
    GPIOD_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;  //Kein Pull-Up oder Pull-Down Widerstand aktiviert&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Speed = GPIO_Speed_25MHz; //25MHz Update-Rate&lt;br /&gt;
    GPIO_Init(GPIOD, &amp;amp;GPIOD_InitStructure);&lt;br /&gt;
&lt;br /&gt;
    GPIO_SetBits(GPIOD, GPIO_Pin_15);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Startup-Code, Linker-Script, Takt, FPU, Optimierung usw.==&lt;br /&gt;
===Startup-Code===&lt;br /&gt;
Em::Blocks fügt standardmäßig einen Startup-Code mit in das Projekt ein. Die wichtigsten Dinge die darin erledigt werden sind folgende:&lt;br /&gt;
&lt;br /&gt;
*Stack und Heap wird angelgt&lt;br /&gt;
*Die Vector-Table wird angelegt&lt;br /&gt;
*Ein Default Reset-Handler wird implementiert, dieser erledigt folgende aufgaben:&lt;br /&gt;
**Kopieren der definierten Daten aus dem Flash in den SRAM&lt;br /&gt;
**&#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; wird aufgerfen, wenn &#039;&#039;&#039;&#039;&#039;__NO_SYSTEM_INIT&#039;&#039;&#039;&#039;&#039; nicht definiert ist&lt;br /&gt;
**Sprung in die &#039;&#039;&#039;&#039;&#039;main()&#039;&#039;&#039;&#039;&#039; Funktion&lt;br /&gt;
*Allen anderen Interrupt-Handler wird eine Default-Funktion &#039;&#039;&#039;&#039;&#039;def_irq_handler&#039;&#039;&#039;&#039;&#039; mit einer &#039;&#039;&#039;&#039;&#039;while(1)&#039;&#039;&#039;&#039;&#039;-Schleife zugewiesen, falls kein anderer Interrupt-Handler existiert.&lt;br /&gt;
&lt;br /&gt;
Normalerweise muss am Startup-Code nichts verändert werden.&lt;br /&gt;
&lt;br /&gt;
===Linker-Script===&lt;br /&gt;
Em::Blocks stellt zwei fertige Linker-Scripts bereit, eins für die Ausführung des Programmes aus dem Flash (&#039;&#039;&#039;&#039;&#039;*_flash.ld&#039;&#039;&#039;&#039;&#039;), das andere für die Ausführung aus dem SRAM (&#039;&#039;&#039;&#039;&#039;*_sram.ld&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Normalerweise muss auch hier nichts geändert werden, es sei den Daten sollen in bestimmten Adressbereichen abgelegt werden (z.B. im Core-Coupled RAM), was ich später noch zum Tutorial hinzufüge.&lt;br /&gt;
&lt;br /&gt;
===Der Takt===&lt;br /&gt;
Jeder Controller oder Prozessor braucht einen Takt, indem er die einzelnen Maschinen-Befehle abarbeiten kann.&lt;br /&gt;
Bei den STM32 Mikrocontrollern kann dieser Takt aus verschiedenen Quellen kommen:&lt;br /&gt;
&lt;br /&gt;
1. High Speed Internal Oszillator (HSI)&lt;br /&gt;
&lt;br /&gt;
2. High Speed External Oszillator (HSE)&lt;br /&gt;
&lt;br /&gt;
3. Low Speed Internal Oszillator (LSI)&lt;br /&gt;
&lt;br /&gt;
4. Low Speed External Oszillator (LSE)&lt;br /&gt;
&lt;br /&gt;
5. Phase-Locked Loop (PLL) (generiert den Takt aus den ersten vier Taktquellen durch Teiler und Faktoren)&lt;br /&gt;
&lt;br /&gt;
Nach einem Reset wird der Controller aus der HSI Taktquelle versorgt (16MHz beim STM32F407VG). Um die voll Performance des Controllers zu erreichen muss die PLL verwendet werden, welche den Takt durch geschickte Teiler und Faktoren vervielfältigt, sodass am Ende der Controller mit der maximalen Taktfrequenz läuft. Die notwendige Initialisierung der PLL findet in der Funktion &#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; statt. Die PLL erzeugt zunächst einen Basistakt:&lt;br /&gt;
&lt;br /&gt;
PLL_VCO = (F_HSE / PLL_M) * PLL_N&lt;br /&gt;
&lt;br /&gt;
Aus diesem Takt wird dann der Takt für den Controller-Kern abgeleitet:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = PLL_VCO / PLL_P&lt;br /&gt;
&lt;br /&gt;
Und der Takt für SDIO / USB / RNG (48MHz):&lt;br /&gt;
&lt;br /&gt;
48MHz = PLL_VCO / PLL_Q&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Durch weiter Teiler werden, die Takte für die einzelnen Busse erzeugt, da diese nicht alle beliebig schnell betrieben werden dürfen.&lt;br /&gt;
&lt;br /&gt;
Genaue Angaben findet man zu dem jeweiligen Clock-System des Controllers im Reference Manual.&lt;br /&gt;
&lt;br /&gt;
Ein Blick in den &amp;quot;Kommentar-Header&amp;quot; verrät, dass von einem externen (HSE) Oszillator von 25MHz ausgegangen wird, der die PLL versorgen soll.&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((25MHz / PLL_M(25)) * PLL_N(336)) / PLL_P(2) = 168MHz&lt;br /&gt;
&lt;br /&gt;
Allerdings stimmt diese Rechnung natürlich nur, wenn wirklich ein 25MHz Quarz am Controller angeschlossen ist. Auf dem STM32F4-Discovery Board befindet sich aber nur ein 8MHz Quarz. Demnach gilt:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((8MHz / PLL_M(25)) * PLL_N(336)) / PLL_P(2) = 53.76MHz&lt;br /&gt;
&lt;br /&gt;
Der Controller läuft also nur mit 53.76MHz, wenn wie ober beschrieben ein Projekt erstellt wird. Allerdings kann dieses Problem durch ändern von den betroffen Defines behoben werden:&lt;br /&gt;
 &lt;br /&gt;
*Dazu geht man in die &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; Datei und passt zur Vollständigkeit erstmal die zum Controller passende Tabelle im &amp;quot;Kommentar-Header&amp;quot; an (Z.57f):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      HSE Frequency(Hz)                      | 8000000&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      PLL_M                                  | 8&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Danach passt man den PPL_M Define (Z.254) an:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/************************* PLL Parameters *************************************/&lt;br /&gt;
/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */&lt;br /&gt;
#define PLL_M      8&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Außerdem muss man den HSE_VALUE Define in der &#039;&#039;&#039;&#039;&#039;inc/stm32f4xx.h&#039;&#039;&#039;&#039;&#039; angepasst werden (Z.122):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#if !defined  (HSE_VALUE)&lt;br /&gt;
  #define HSE_VALUE    ((uint32_t)8000000) /*!&amp;lt; Value of the External oscillator in Hz */&lt;br /&gt;
&lt;br /&gt;
#endif /* HSE_VALUE */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine neue Berechnung zeigt:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((8MHz / PLL_M(8)) * PLL_N(336)) / PLL_P(2) = 168MHz&lt;br /&gt;
&lt;br /&gt;
Jetzt läuft der Controller mit maximaler Geschwindigkeit.&lt;br /&gt;
&lt;br /&gt;
Die Theorie wird durch folgendes Programm verifiziert. Der geviertelte System-Takt SYSCLK wir am Pin PC9 ausgegeben. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);&lt;br /&gt;
&lt;br /&gt;
    GPIO_InitTypeDef GPIOC_InitStructure;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Mode = GPIO_Mode_AF;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_OType = GPIO_OType_PP;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Pin = GPIO_Pin_9;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;&lt;br /&gt;
    GPIO_Init(GPIOC, &amp;amp;GPIOC_InitStructure);&lt;br /&gt;
&lt;br /&gt;
    RCC_MCO2Config(RCC_MCO2Source_SYSCLK, RCC_MCO2Div_4);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Die FPU===&lt;br /&gt;
====Allgemeines====&lt;br /&gt;
Damit die FPU richtig verwendet wird, müssen normalerweise zwei Bedingungen erfüllt sein:&lt;br /&gt;
&lt;br /&gt;
1. Der Controller muss in der Initialisierung-Funktion &#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; in &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; die FPU Hardware-seitig aktivieren&lt;br /&gt;
&lt;br /&gt;
2. Damit die FPU auch was zu tuen bekommt, müssen vom Compiler FPU-Instructions erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
Die Em::Blocks IDE verwendet standardmäßig die FPU, wenn eine Vorhanden ist. Hier wird die FPU Hardware-seitig aktiviert (&#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; Z.341):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* FPU settings ------------------------------------------------------------*/&lt;br /&gt;
  #if (__FPU_PRESENT == 1) &amp;amp;&amp;amp; (__FPU_USED == 1)&lt;br /&gt;
    SCB-&amp;gt;CPACR |= ((3UL &amp;lt;&amp;lt; 10*2)|(3UL &amp;lt;&amp;lt; 11*2));  /* set CP10 and CP11 Full Access */&lt;br /&gt;
  #endif&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
__FPU_PRESENT wird in der &#039;&#039;&#039;&#039;&#039;stm32f4xx.h&#039;&#039;&#039;&#039;&#039; definiert.&lt;br /&gt;
__FPU_USED wird von der IDE übernommen (siehe Build-Log): &#039;&#039;&#039;&#039;&#039;-D__FPU_USED&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Außerdem wird der Compiler von der IDE standardmäßig mit dem Argument &#039;&#039;&#039;&#039;&#039;-mfloat-abi=hard&#039;&#039;&#039;&#039;&#039; aufgerufen, wodurch FPU-Instructions erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
====FPU abschalten====&lt;br /&gt;
Um die FPU ab zu schalten (Mir würde jetzt nur Strom sparen als Grund einfallen) geht man wie folgt vor:&lt;br /&gt;
&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick Build options -&amp;gt; Device -&amp;gt; Policy&#039;&#039;&#039;&#039;&#039; wählt man &#039;&#039;&#039;&#039;&#039;Use target settings&#039;&#039;&#039;&#039;&#039; und über nimmt die Einstellungen, die vorher dort eingetragen waren, allerdings lässt man das Feld &#039;&#039;&#039;&#039;&#039;FP-hardware&#039;&#039;&#039;&#039;&#039; frei.&lt;br /&gt;
&lt;br /&gt;
[[Datei:fpu_1.png|FPU Abschalten Schritt 1]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;Compiler Settings -&amp;gt; Policy&#039;&#039;&#039;&#039;&#039; wählt man dann &#039;&#039;&#039;&#039;&#039;Use target options only&#039;&#039;&#039;&#039;&#039;. Dann kann man unter &#039;&#039;&#039;&#039;&#039;Categories&#039;&#039;&#039;&#039;&#039; die Option &#039;&#039;&#039;&#039;&#039;ARM FPU architecture&#039;&#039;&#039;&#039;&#039; auswählen. Dort stehen dann drei Möglichkeiten für die FPU zur Verfügung:&lt;br /&gt;
&lt;br /&gt;
1. Software-FPU-Library für Gleitkomma-Berechnung verwenden - Keine FPU-Instructions werden generiert (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=soft&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
2. Eine Mischung aus Software- und Hardware-FPU wird verwendet (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=softfp&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
3. Hardware-FPU wird für Gleitkomma-Berechnungen verwendet (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=hard&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
[[Datei:fpu_2.png|FPU Abschalten Schritt 2]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Um die FPU ab zu schalten wählt man natürlich die erste Möglichkeit.&lt;br /&gt;
Bei der 2. und 3. Möglichkeit fügt die IDE auch den Define &#039;&#039;&#039;&#039;&#039;__FPU_USED&#039;&#039;&#039;&#039;&#039; hinzu. Bei Der ersten Möglichkeit nicht. Der Code muss also nicht verändert / auskommentiert werden.&lt;br /&gt;
&lt;br /&gt;
Um die FPU wieder zu aktivieren müssen alle Schritte wieder rückgängig gemacht werden.&lt;br /&gt;
&lt;br /&gt;
Am besten ist es einfach mal alle Möglichkeiten im Einzelschritt durch zu probieren. Dann stellt man schnell fest, ob die FPU aktiviert wir oder nicht. Ein Blick in den erweiterten &#039;&#039;&#039;&#039;&#039;Build-Log&#039;&#039;&#039;&#039;&#039; gibt auch schnell Aufschluss darüber, wie der Compiler aufgerufen wird (siehe Kapitel [http://www.mikrocontroller.net/articles/STM32_-_Einstieg_mit_Em::Blocks#Compilieren Compilieren]).&lt;br /&gt;
&lt;br /&gt;
====Test Programm für die FPU====&lt;br /&gt;
Hier ein kleines Testprogramm, dass misst wie viele Taktzyklen für eine Gleitkomma-Multiplikation gebraucht werden. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define CORE_SysTickEn()    (*((u32*)0xE0001000)) = 0x40000001&lt;br /&gt;
#define CORE_SysTickDis()   (*((u32*)0xE0001000)) = 0x40000000&lt;br /&gt;
#define CORE_GetSysTick()   (*((u32*)0xE0001004))&lt;br /&gt;
&lt;br /&gt;
uint32_t t1, t2, dt;&lt;br /&gt;
float x, y, z;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    x = 53.64f;&lt;br /&gt;
    y = 0.27f;&lt;br /&gt;
&lt;br /&gt;
    CORE_SysTickEn();&lt;br /&gt;
    t1 = CORE_GetSysTick();&lt;br /&gt;
&lt;br /&gt;
    z = x * y;&lt;br /&gt;
&lt;br /&gt;
    t2 = CORE_GetSysTick();&lt;br /&gt;
    CORE_SysTickDis();&lt;br /&gt;
&lt;br /&gt;
    dt = (t2 - t1) - 9; //9 Takt-Zyklen werden für die Messung gebraucht &lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Compiler-Optimierung===&lt;br /&gt;
&lt;br /&gt;
==Booten aus dem SRAM==&lt;br /&gt;
STM32 Controller haben die Möglichkeit Code aus dem Flash als auch aus dem SRAM auszuführen. Um eine Anwenung per Debugger in des SRAM zu laden sind nur wenige Schritte erforderlich:&lt;br /&gt;
&lt;br /&gt;
*Um das Linkerscript für den SRAM zu verwenden geht man zu: &#039;&#039;&#039;&#039;&#039;Build options... -&amp;gt; Device&#039;&#039;&#039;&#039;&#039; dort wählt man unter &#039;&#039;&#039;&#039;&#039;Policy&#039;&#039;&#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;Use target settings&#039;&#039;&#039;&#039;&#039; aus und übernimmt die vorherigen Einstellungen, nur unter &#039;&#039;&#039;&#039;&#039;Linker script*&#039;&#039;&#039;&#039;&#039; gibt man &#039;&#039;&#039;&#039;&#039;.\stm32f407vg_sram.ld&#039;&#039;&#039;&#039;&#039; an&lt;br /&gt;
&lt;br /&gt;
*Dann muss man noch unter &#039;&#039;&#039;&#039;&#039;Debug -&amp;gt; Interfaces -&amp;gt; Settings&#039;&#039;&#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;Vector table start&#039;&#039;&#039;&#039;&#039; auf 0x20000000 ändern und &#039;&#039;&#039;&#039;&#039;Execute from RAM&#039;&#039;&#039;&#039;&#039; auswählen.&lt;br /&gt;
&lt;br /&gt;
Anschließend kann man die Anwendung ganz normal debuggen. Nach einem Reset muss die Anwenung erneut mit dem Debugger gestartet werden.&lt;br /&gt;
&lt;br /&gt;
=Fortsetzung folgt..=&lt;br /&gt;
Kritik, Wünsche usw. sind gerne erwünscht, am besten hier in den Thread posten: [http://www.mikrocontroller.net/topic/323750 Neues STM32 Tutorial]&lt;br /&gt;
&lt;br /&gt;
[[Category:ARM]]&lt;br /&gt;
[[Category:STM32]]&lt;/div&gt;</summary>
		<author><name>Avrprogger</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=STM32_-_Einstieg_mit_Em::Blocks&amp;diff=81519</id>
		<title>STM32 - Einstieg mit Em::Blocks</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=STM32_-_Einstieg_mit_Em::Blocks&amp;diff=81519"/>
		<updated>2014-02-10T21:19:20Z</updated>

		<summary type="html">&lt;p&gt;Avrprogger: dfg&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In diesem Tutorial werde ich versuchen, möglichst einfach, die ersten Schritte zur Entwicklung von STM32 Anwenungen mit der Em::Blocks IDE zu erklären. Hier soll nicht so stark auf die einzelnen Peripherie-Module der Controller eingegangen werden, sondern mehr auf die IDE und die verschieden Libraries, wie die CMSIS Library, die DSP-Library, die Standard-Peripheral-Library, die USB-Library und vllt. über Ethernet. Ich denke ein Kapitel zu FreeRTOS wird es auch geben. Auserdem steht im Vordergrund Sachen wie z.B. booten aus dem SRAM, In-Application-Programming, FPU, Core-Coupled-RAM usw. Mal sehn wie weit ich komme ;)&lt;br /&gt;
&lt;br /&gt;
==Die Entwicklungsumgebung==&lt;br /&gt;
===Hardware===&lt;br /&gt;
Zum testen der Anwendungen, benutze ich das STM32F4-Discovery Board, welches einen Debugger, Peripherie und natürlich einen STM32 Controller (STM32F407VGT6) enthält. Deshalb sind alle Beispiele hier für den STM32F407VG Controller ausgelegt, können aber meisten 1:1 auf andere Controller portiert werden. Ich werde auch möglichsts keine STM32F4-Discovery Board spezifischen Libraries verwenden, damit der Portierungs-Vorgang möglichsts einfach bleibt.&lt;br /&gt;
&lt;br /&gt;
===Software===&lt;br /&gt;
In diesem Tutorial verwende ich [http://www.emblocks.org/ Em::Blocks] als IDE. Em::Blocks ist eine kostenlose, uneingeschränkte IDE, die alle STM32 Mikrcontroller unterstützt und sehr einfach zu bedienen ist.&lt;br /&gt;
nach dem Download kann die IDE per Dialog, sehr einfach, installiert werden. Als Compiler beinhaltet Em::Blocks den &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
Die IDE unterstützt zurzeit den ST-Link, den J-Link und es gibt eine Generic-Vorlage, durch welche andere Debugger konfiguriert werden können.&lt;br /&gt;
&lt;br /&gt;
Außerdem muss noch der passende Treiber für den Debugger installiert werden. Verwendet man ein Discovery-Board muss der [http://www.st.com/web/catalog/tools/FM146/CL1984/SC724/SS1677/PF251168 ST-Link/V2]-Treiber heruntergeladen und installiert werden. (Die Installation muss evtl. als Administrator ausgeführt werden, da sonst die Installation unvollständig wird.) Nach der Installation des Treibers kann man den Debugger über die entsprechende USB Schnittstelle an den PC anschließen und es sollte die Meldung von Windows kommen, dass der richtige Treiber gefunden wurde.&lt;br /&gt;
&lt;br /&gt;
===Libraries===&lt;br /&gt;
Zum programmieren benötigt man noch die [http://www.arm.com/products/processors/cortex-m/cortex-microcontroller-software-interface-standard.php CMSIS] und die Standard-Peripheral-Library (z.B. für die F4 Controller [http://www.st.com/stonline/stappl/productcatalog/app?page=partNumberSearchPage&amp;amp;levelid=SS1577&amp;amp;parentid=1743&amp;amp;resourcetype=SW Standard-Peripheral-Library-F4]), die man am besten in einen Ordner (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\STM32&#039;&#039;&#039;&#039;&#039;) entpackt&lt;br /&gt;
&lt;br /&gt;
==Basis-Wissen zur IDE==&lt;br /&gt;
Einige Grundfunktionalitäten der IDE:&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von Dateien zum Projekt===&lt;br /&gt;
Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf &amp;lt;ProjektName&amp;gt; -&amp;gt; Add files...&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Enfernen von Dateien aus dem Projekt===&lt;br /&gt;
Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf die Datei / mehrere Dateien auswählen -&amp;gt; Remove file from project&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
Die Dateien werden lediglich aus dem Projekt entfernt und nicht von der Festplatte gelöscht.&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von Include-Pfaden===&lt;br /&gt;
Sofern die Include-Datei(en) nicht im standard Include-Ordner &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; des Projektes liegen, muss man den Pfad zum Projekt hinzufügen, damit der Compiler die Include-Dateien später auch finden kann. Man geht wie folgt vor: Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf &amp;lt;ProjektName&amp;gt; -&amp;gt; Build options... -&amp;gt; Search Directories -&amp;gt; Add&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Compilieren===&lt;br /&gt;
Entweder über das &#039;&#039;&#039;&#039;&#039;Build&#039;&#039;&#039;&#039;&#039; Menü oder über &#039;&#039;&#039;&#039;&#039;F7&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Um eine genau Ausgabe des Compiler-Aufrufes mit allen Argumenten zu bekommen, geht man im &#039;&#039;&#039;&#039;&#039;Settings&#039;&#039;&#039;&#039;&#039; Menü auf &#039;&#039;&#039;&#039;&#039;Tools...&#039;&#039;&#039;&#039;&#039; und dann auf &#039;&#039;&#039;&#039;&#039;Toolchain executables&#039;&#039;&#039;&#039;&#039;. Ganz unten, unter &#039;&#039;&#039;&#039;&#039;Logging&#039;&#039;&#039;&#039;&#039; kann man dann &#039;&#039;&#039;&#039;&#039;Full command line&#039;&#039;&#039;&#039;&#039; auswählen.&lt;br /&gt;
&lt;br /&gt;
===Debuggen===&lt;br /&gt;
*Als erstes den Debugger starten über das &#039;&#039;&#039;&#039;&#039;Debug&#039;&#039;&#039;&#039;&#039; Menü und &#039;&#039;&#039;&#039;&#039;Start/stop Debug Session&#039;&#039;&#039;&#039;&#039; oder über &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
*Danach läuft die Anwendung auf dem Controller und warten im &#039;&#039;&#039;&#039;&#039;Reset_Handler&#039;&#039;&#039;&#039;&#039; auf Einzelschritt- bzw. Run- Befehle (&#039;&#039;&#039;&#039;&#039;F5, F10, F11&#039;&#039;&#039;&#039;&#039; usw..(siehe &#039;&#039;&#039;&#039;&#039;Debug-Menü&#039;&#039;&#039;&#039;&#039; für alle Möglichkeiten))&lt;br /&gt;
&lt;br /&gt;
*Mit &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039; wird die Debug-Session auch wieder beendet&lt;br /&gt;
&lt;br /&gt;
*Unter &#039;&#039;&#039;&#039;&#039;Debug -&amp;gt; Interfaces -&amp;gt; Target settings&#039;&#039;&#039;&#039;&#039; können Eigenschaften, wie z.B &#039;&#039;&#039;&#039;&#039;Run to main()&#039;&#039;&#039;&#039;&#039; aktiviert werden.&lt;br /&gt;
&lt;br /&gt;
===Projekt als Template abspeichern===&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;File -&amp;gt; Save project as template...&#039;&#039;&#039;&#039;&#039;. Das Template erscheint dann im Projekt-Dialog unter &#039;&#039;&#039;&#039;&#039;User templates&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Das erste Projekt erstellen==&lt;br /&gt;
Hier erkläre ich, wie man am Besten (aus meiner Sicht), ein neues Projekt von Grund auf erstellt, sodass man hinterher, den Controller-Kern über die CMSIS-Library und die Peripherie über die Register steuern kann.&lt;br /&gt;
&lt;br /&gt;
===1. Projekt mit der IDE erstellen===&lt;br /&gt;
Nach der Installation der oben beschriebenen Komponenten erstellt man am besten ein Verzeichnis (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\EmBlocks&#039;&#039;&#039;&#039;&#039;), indem später alle Projekte gespeichert werden. Für Libraries kann man auch noch ein Verzeichnis (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\STM32&#039;&#039;&#039;&#039;&#039;) erstellen, wo alle Libraries gespeichert werden, die man für die Projekt brauchen.&lt;br /&gt;
&lt;br /&gt;
Als nächstes starten man EmBlocks. Bei dem ersten Start öffnet sich ein Fenster, wo verschiedene Compiler angezeigt werden, die Em::Blocks findet. Dort wählt man den &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039; aus und klickt &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039;. Nun sollte sich das Hauptfenster von Em::Blocks öffnen. Über &#039;&#039;&#039;&#039;&#039;Create a new Project&#039;&#039;&#039;&#039;&#039; oder &#039;&#039;&#039;&#039;&#039;File -&amp;gt; New -&amp;gt; Project&#039;&#039;&#039;&#039;&#039; ruft man den Projekt-Dialog auf und kann ein neues Projekt erzeugen.&lt;br /&gt;
&lt;br /&gt;
Auf der Ersten Seite wählen man den &#039;&#039;&#039;&#039;&#039;STmicro-ARM&#039;&#039;&#039;&#039;&#039; Projekt-Typ aus.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_1.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auf der nächsten Seite wird man darauf hingewiesen, dass das der entsprechende Projekt-Typ-Dialog ausgeführt wird. Hier kann man ein Häkchen bei &#039;&#039;&#039;&#039;&#039;Skip this page next time&#039;&#039;&#039;&#039;&#039; setzen und auf &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; klicken.&lt;br /&gt;
&lt;br /&gt;
Im nächsten Schritt wählen man das zuvor erstellt Verzeichnis unter &#039;&#039;&#039;&#039;&#039;Folder to create Project in&#039;&#039;&#039;&#039;&#039; aus, indem später alle Projekt gespeichert werden. Außerdem geben wir dem Projekt einen Namen (z.B. &#039;&#039;&#039;&#039;&#039;FirstProject&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_2.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danach muss man einen Compiler auswählen und bestimmen, welche Projekt-Konfigurationen erszeugt werden sollen. Unter &#039;&#039;&#039;&#039;&#039;Compiler&#039;&#039;&#039;&#039;&#039; wählt man &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039; und man kann das Häkchen bei &#039;&#039;&#039;&#039;&#039;Create &amp;quot;Release&amp;quot; configuration&#039;&#039;&#039;&#039;&#039; entfernen, da diese unnötig ist, die Debug-Konfiguration sollte eig. immer ausreichen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_3.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auf den folgenden Seite wird der Controller ausgewählt. Verwendet man ein STM32F4-Discovery Board müssen folgende Dinge gewählt werden: &#039;&#039;&#039;&#039;&#039;Cortex_M4 (F3xx - F4xx) -&amp;gt; STM32F4xx (Cortex M4 with FPU) -&amp;gt; STM32F407VG&#039;&#039;&#039;&#039;&#039;. Leider sind die Auswahl Möglichkeiten nicht ganz richtig, da auch die F3 Controller einen Cortex M4 Kern und eine FPU haben (Ist aber nicht so wichtig, ist nur eine formale Sache). Außerdem entfernt man das Häkchen bei &#039;&#039;&#039;&#039;&#039;Standard Peripherals Library&#039;&#039;&#039;&#039;&#039; (Wie man die Standard-Peripheral-Library einbindet und verwendet erkläre ich später). Man kann auch das Häkchen bei &#039;&#039;&#039;&#039;&#039;Create hex file for Realease target&#039;&#039;&#039;&#039;&#039; entfernen.&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;Stack Size&#039;&#039;&#039;&#039;&#039; und &#039;&#039;&#039;&#039;&#039;Heap Size&#039;&#039;&#039;&#039;&#039; wird die Größe von Stack und Heap festgelegt. Für eine erste Anwendung kann man die Einstellungen so lassen (Stack-Size: 0x0100 =&amp;gt; 256 Byte Stack und Heap-Size: 0x0000 =&amp;gt; kein Heap). Mit &#039;&#039;&#039;&#039;&#039;Finish&#039;&#039;&#039;&#039;&#039; ist der Projekt Dialog abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_4.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danach sollten sich zwei neue Fenster öffnen, um die Debug-Eigenschaften fest zu legen.&lt;br /&gt;
Verwendet man ein Discovery Board/ST-Link müssen die Einstellungen wie auf dem Bild gewählt werden. Über den Button &#039;&#039;&#039;&#039;&#039;Settings&#039;&#039;&#039;&#039;&#039; öffnet sich das zweite Fenster, falls sich dieses nicht schon von alleine öffnen sollte. Nach den Schließen der Fenster über &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; ist der Projekt Dialog beendet und ein neues Projekt steht zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_5_1.png|Debug Eigenschaften 1. Fenster]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_5_2.png|Debug Eigenschaften 2. Fenster]]&lt;br /&gt;
&lt;br /&gt;
===2. CMSIS-Library und Startup-Code hinzufügen===&lt;br /&gt;
Wenn man sich, nachdem man ein neues Projekt in der IDE erstellt hat, die bereits vorhandenen Dateien im Projekt ansieht, stellt man fest, das bereits ein Ordner &#039;&#039;&#039;&#039;&#039;cmsis&#039;&#039;&#039;&#039;&#039; existiert, der einige wichtige Include-Dateien der CMSIS-Library enthält. Allerdings sind das wirklich nur die wichtigsten Include-Dateien der CMSIS-Library und dazu noch, die aus einer älternen Version. Ich ziehe es deshalb vor die &amp;quot;Mini-CMSIS-Libraray&amp;quot; und die &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c/.h&#039;&#039;&#039;&#039;&#039; Dateien des Projektes durch aktuellere Versionen zu ersetzen. So ist später auch die Integration  von anderen Libraries, wie z.B. der CMSIS-DSP-Libarary einfacher.  &lt;br /&gt;
&lt;br /&gt;
Zunächst gehen man in das Projekt-Verzeichnis und löscht:&lt;br /&gt;
*Den Ordner &#039;&#039;&#039;&#039;&#039;cmsis&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Alle Dateien im Include Verzeichnis &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; im &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner&lt;br /&gt;
&lt;br /&gt;
Außerdem entfernt man auch alle gelöschten Dateien in der IDE aus dem Projekt mit &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Rechts Klick -&amp;gt; Remove file from project&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Es sollte folgende Verzeichnis Struktur überbleiben:&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_6.png|Überbleibende Dateien]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Jetzt müssen die gelöschten Dateien durch die aktuelleren ersetzt werden.&lt;br /&gt;
&lt;br /&gt;
*Dazu kopieren man den gesamten Ordner &#039;&#039;&#039;&#039;&#039;CMSIS&#039;&#039;&#039;&#039;&#039; aus dem CMSIS Download in das Projekt Verzeichnis.&lt;br /&gt;
&lt;br /&gt;
*Aus dem Standard-Peripheral-Library Download kopiert man von &#039;&#039;&#039;&#039;&#039;Libraries\CMSIS\Device\ST\STM32F4xx\Include&#039;&#039;&#039;&#039;&#039; alle Dateien in den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projekt Verzeichnisses&lt;br /&gt;
&lt;br /&gt;
*Aus der Standard-Peripheral-Library kopieren man ebenfalls von &#039;&#039;&#039;&#039;&#039;Libraries\CMSIS\Device\ST\STM32F4xx\Source\Templates&#039;&#039;&#039;&#039;&#039; die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; in den &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner des Projekts&lt;br /&gt;
&lt;br /&gt;
Anschließend müssen die neuen Dateien in der IDE dem Projekt hinzugefügt werden. Dazu benutzt man &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Rechts Klick -&amp;gt; Add files&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
*Aus dem &#039;&#039;&#039;&#039;&#039;CMSIS&#039;&#039;&#039;&#039;&#039; Ordner im Projekt Verzeichnis werden aus den Unterorder &#039;&#039;&#039;&#039;&#039;Include&#039;&#039;&#039;&#039;&#039; folgende Dateien dem Projekt hinzugefügt:&lt;br /&gt;
**arm_common_tables.h&lt;br /&gt;
**arm_const_structs.h&lt;br /&gt;
**arm_math.h&lt;br /&gt;
**core_cm4.h&lt;br /&gt;
**core_cm4_simd.h&lt;br /&gt;
**core_cmFunc.h&lt;br /&gt;
**core_cmInstr.h&lt;br /&gt;
*Alle Dateien aus den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projektes&lt;br /&gt;
*Die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; aus dem &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner&lt;br /&gt;
&lt;br /&gt;
So sollte die Struktur dann aussehen:&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_7.png|Anwenungs-Grundgerüst]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Da einige Dateien der Libraries später bearbeitet werden müssen und Schreibgeschützt sind, weise ich hier schonmal darauf hin, das der Schreibschutz in der IDE über &#039;&#039;&#039;&#039;&#039;Rechts Klick auf die Datei -&amp;gt; Properties -&amp;gt; Häkchen bei &amp;quot;File is read only&amp;quot; entfernen&#039;&#039;&#039;&#039;&#039; entfert werden kann.&lt;br /&gt;
&lt;br /&gt;
Damit die IDE die Header-Dateien der CMSIS Library auch finden kann, weil diese ja nicht im standard Include Ordner &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; liegen, muss unter &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Build Options -&amp;gt; Search Directories&#039;&#039;&#039;&#039;&#039; der Pfad &#039;&#039;&#039;&#039;&#039;CMSIS\Include&#039;&#039;&#039;&#039;&#039; hinzugefügt werden.&lt;br /&gt;
&lt;br /&gt;
Compiliert man jetzt das Projekt mit &#039;&#039;&#039;&#039;&#039;F7&#039;&#039;&#039;&#039;&#039; gibt es ein paar Fehler Meldungen, weil keine Controller-Reihe ausgewählt wurde. Ebenfalls unter &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Build Options -&amp;gt; Compiler Settings -&amp;gt; #defines&#039;&#039;&#039;&#039;&#039; wird der Define &#039;&#039;&#039;&#039;&#039;STM32F40_41xxx&#039;&#039;&#039;&#039;&#039; hinzugefügt.&lt;br /&gt;
&lt;br /&gt;
Beim erneuten Compilieren sollten sich nun keine neuen Fehler ergeben.&lt;br /&gt;
&lt;br /&gt;
===Das erste Programm===&lt;br /&gt;
Nachdem ein grundsätzliches &amp;quot;Gerüst&amp;quot; fertig ist, kann man den ersten Code schreiben.&lt;br /&gt;
main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC-&amp;gt;AHB1ENR |= RCC_AHB1ENR_GPIODEN;    //Takt für GPIO aktivieren&lt;br /&gt;
    GPIOD-&amp;gt;MODER |= GPIO_MODER_MODER15_0;   //GPIOD Pin15 als Ausgang&lt;br /&gt;
    GPIOD-&amp;gt;BSRRL |= GPIO_BSRR_BS_15;        //GPIOD Pin15 auf High ziehen&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039; wird dann der Debugger gestartet. Hat der Debugger das Projekt erfolgreich übertragen kann die Ausführung mit &#039;&#039;&#039;&#039;&#039;F5&#039;&#039;&#039;&#039;&#039; begonnen werden.&lt;br /&gt;
&lt;br /&gt;
==Libraries einbinden/verwenden==&lt;br /&gt;
===Einbinden der Standard-Peripheral-Library===&lt;br /&gt;
Um nicht immer die einzelnen Register, wie im ersten &amp;quot;bare-metal&amp;quot; Beispiel, aus dem Reference-Manual zu suchen und zu beschreiben, gibt es von ST die Standard Peripheral Library, die diese Aufgaben übernimmt und mit der sich die &amp;quot;normale/grundlegende&amp;quot; (Alles außer USB und Ethernet) Peripherie recht einfach steuern lässt. Um die Library zu verwenden erzeugt man wie oben beschrieben ein neues Grundgerüst und kopiert als erstes den Ordner &#039;&#039;&#039;&#039;&#039;Libraries\STM32F4xx_StdPeriph_Driver&#039;&#039;&#039;&#039;&#039; aus dem Standard-Peripheral-Library Download in das Projekt-Verzeichnis. Außerdem muss man die Datei &#039;&#039;&#039;&#039;&#039;Project\STM32F4xx_StdPeriph_Templates\stm32f4xx_conf.h&#039;&#039;&#039;&#039;&#039; ebenfalls aus dem Standard-Peripheral-Library Download in den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projektes kopieren. In der IDE fügt man den Include-Path &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\inc&#039;&#039;&#039;&#039;&#039; hinzufügen, wie bei der CMSIS-Library (s.o.).&lt;br /&gt;
Außerdem muss noch &#039;&#039;&#039;&#039;&#039;USE_STDPERIPH_DRIVER&#039;&#039;&#039;&#039;&#039; als Define in der IDE hinzugefügt werden (s.o.).&lt;br /&gt;
Danach fügt man die Source- und Include-Dateien aus dem Ordner &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\inc&#039;&#039;&#039;&#039;&#039; und &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\src&#039;&#039;&#039;&#039;&#039; dem Project mit &#039;&#039;&#039;&#039;&#039;&amp;lt;Project Name&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Add files&#039;&#039;&#039;&#039;&#039; hinzu, allerdings nur die, für welche auch der Controller die entsprechende Peripherie besitzt. Beim STM32F4-Discovery Board / STM32F407VG Controller dürfen also nicht folgende Dateien nicht mit hinzugefügt werden, weil diese Peripherie nur bei anderen Controller vorhanden ist:&lt;br /&gt;
&lt;br /&gt;
*stm32f4xx_dma2d.c/.h&lt;br /&gt;
*stm32f4xx_fmc.c/.h&lt;br /&gt;
*stm32f4xx_ltdc.c/.h&lt;br /&gt;
*stm32f4xx_sai.c/.h&lt;br /&gt;
&lt;br /&gt;
Daraus resultiert folgende Struktur:&lt;br /&gt;
&lt;br /&gt;
[[Datei:stdperiphlib_2.png|Header-Struktur]] [[Datei:stdperiphlib_1.png|Source-Struktur]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Anschließen kann die Standard-Peripheral-Library benutz werden.&lt;br /&gt;
main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);&lt;br /&gt;
&lt;br /&gt;
    GPIO_InitTypeDef GPIOD_InitStructure;&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Mode = GPIO_Mode_OUT;     //Als Ausgang&lt;br /&gt;
    GPIOD_InitStructure.GPIO_OType = GPIO_OType_PP;    //Push-Pull Betrieb&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Pin = GPIO_Pin_15;        //Pin 15 (STM32F4-Discovery: Blaue LED)&lt;br /&gt;
    GPIOD_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;  //Kein Pull-Up oder Pull-Down Widerstand aktiviert&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Speed = GPIO_Speed_25MHz; //25MHz Update-Rate&lt;br /&gt;
    GPIO_Init(GPIOD, &amp;amp;GPIOD_InitStructure);&lt;br /&gt;
&lt;br /&gt;
    GPIO_SetBits(GPIOD, GPIO_Pin_15);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Startup-Code, Linker-Script, Takt, FPU, Optimierung usw.==&lt;br /&gt;
===Startup-Code===&lt;br /&gt;
Em::Blocks fügt standardmäßig einen Startup-Code mit in das Projekt ein. Die wichtigsten Dinge die darin erledigt werden sind folgende:&lt;br /&gt;
&lt;br /&gt;
*Stack und Heap wird angelgt&lt;br /&gt;
*Die Vector-Table wird angelegt&lt;br /&gt;
*Ein Default Reset-Handler wird implementiert, dieser erledigt folgende aufgaben:&lt;br /&gt;
**Kopieren der definierten Daten aus dem Flash in den SRAM&lt;br /&gt;
**&#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; wird aufgerfen, wenn &#039;&#039;&#039;&#039;&#039;__NO_SYSTEM_INIT&#039;&#039;&#039;&#039;&#039; nicht definiert ist&lt;br /&gt;
**Sprung in die &#039;&#039;&#039;&#039;&#039;main()&#039;&#039;&#039;&#039;&#039; Funktion&lt;br /&gt;
*Allen anderen Interrupt-Handler wird eine Default-Funktion &#039;&#039;&#039;&#039;&#039;def_irq_handler&#039;&#039;&#039;&#039;&#039; mit einer &#039;&#039;&#039;&#039;&#039;while(1)&#039;&#039;&#039;&#039;&#039;-Schleife zugewiesen, falls kein anderer Interrupt-Handler existiert.&lt;br /&gt;
&lt;br /&gt;
Normalerweise muss am Startup-Code nichts verändert werden.&lt;br /&gt;
&lt;br /&gt;
===Linker-Script===&lt;br /&gt;
Em::Blocks stellt zwei fertige Linker-Scripts bereit, eins für die Ausführung des Programmes aus dem Flash (&#039;&#039;&#039;&#039;&#039;*_flash.ld&#039;&#039;&#039;&#039;&#039;), das andere für die Ausführung aus dem SRAM (&#039;&#039;&#039;&#039;&#039;*_sram.ld&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Normalerweise muss auch hier nichts geändert werden, es sei den Daten sollen in bestimmten Adressbereichen abgelegt werden (z.B. im Core-Coupled RAM), was ich später noch zum Tutorial hinzufüge.&lt;br /&gt;
&lt;br /&gt;
===Der Takt===&lt;br /&gt;
Jeder Controller oder Prozessor braucht einen Takt, indem er die einzelnen Maschinen-Befehle abarbeiten kann.&lt;br /&gt;
Bei den STM32 Mikrocontrollern kann dieser Takt aus verschiedenen Quellen kommen:&lt;br /&gt;
&lt;br /&gt;
1. High Speed Internal Oszillator (HSI)&lt;br /&gt;
&lt;br /&gt;
2. High Speed External Oszillator (HSE)&lt;br /&gt;
&lt;br /&gt;
3. Low Speed Internal Oszillator (LSI)&lt;br /&gt;
&lt;br /&gt;
4. Low Speed External Oszillator (LSE)&lt;br /&gt;
&lt;br /&gt;
5. Phase-Locked Loop (PLL) (generiert den Takt aus den ersten vier Taktquellen durch Teiler und Faktoren)&lt;br /&gt;
&lt;br /&gt;
Nach einem Reset wird der Controller aus der HSI Taktquelle versorgt (16MHz beim STM32F407VG). Um die voll Performance des Controllers zu erreichen muss die PLL verwendet werden, welche den Takt durch geschickte Teiler und Faktoren vervielfältigt, sodass am Ende der Controller mit der maximalen Taktfrequenz läuft. Die notwendige Initialisierung der PLL findet in der Funktion &#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; statt. Die PLL erzeugt zunächst einen Basistakt:&lt;br /&gt;
&lt;br /&gt;
PLL_VCO = (F_HSE / PLL_M) * PLL_N&lt;br /&gt;
&lt;br /&gt;
Aus diesem Takt wird dann der Takt für den Controller-Kern abgeleitet:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = PLL_VCO / PLL_P&lt;br /&gt;
&lt;br /&gt;
Und der Takt für SDIO / USB / RNG (48MHz):&lt;br /&gt;
&lt;br /&gt;
48MHz = PLL_VCO / PLL_Q&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Durch weiter Teiler werden, die Takte für die einzelnen Busse erzeugt, da diese nicht alle beliebig schnell betrieben werden dürfen.&lt;br /&gt;
&lt;br /&gt;
Genaue Angaben findet man zu dem jeweiligen Clock-System des Controllers im Reference Manual.&lt;br /&gt;
&lt;br /&gt;
Ein Blick in den &amp;quot;Kommentar-Header&amp;quot; verrät, dass von einem externen (HSE) Oszillator von 25MHz ausgegangen wird, der die PLL versorgen soll.&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((25MHz / PLL_M(25)) * PLL_N(336)) / PLL_P(2) = 168MHz&lt;br /&gt;
&lt;br /&gt;
Allerdings stimmt diese Rechnung natürlich nur, wenn wirklich ein 25MHz Quarz am Controller angeschlossen ist. Auf dem STM32F4-Discovery Board befindet sich aber nur ein 8MHz Quarz. Demnach gilt:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((8MHz / PLL_M(25)) * PLL_N(336)) / PLL_P(2) = 53.76MHz&lt;br /&gt;
&lt;br /&gt;
Der Controller läuft also nur mit 53.76MHz, wenn wie ober beschrieben ein Projekt erstellt wird. Allerdings kann dieses Problem durch ändern von den betroffen Defines behoben werden:&lt;br /&gt;
 &lt;br /&gt;
*Dazu geht man in die &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; Datei und passt zur Vollständigkeit erstmal die zum Controller passende Tabelle im &amp;quot;Kommentar-Header&amp;quot; an (Z.57f):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      HSE Frequency(Hz)                      | 8000000&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      PLL_M                                  | 8&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Danach passt man den PPL_M Define (Z.254) an:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/************************* PLL Parameters *************************************/&lt;br /&gt;
/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */&lt;br /&gt;
#define PLL_M      8&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Außerdem muss man den HSE_VALUE Define in der &#039;&#039;&#039;&#039;&#039;inc/stm32f4xx.h&#039;&#039;&#039;&#039;&#039; angepasst werden (Z.122):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#if !defined  (HSE_VALUE)&lt;br /&gt;
  #define HSE_VALUE    ((uint32_t)8000000) /*!&amp;lt; Value of the External oscillator in Hz */&lt;br /&gt;
&lt;br /&gt;
#endif /* HSE_VALUE */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine neue Berechnung zeigt:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((8MHz / PLL_M(8)) * PLL_N(336)) / PLL_P(2) = 168MHz&lt;br /&gt;
&lt;br /&gt;
Jetzt läuft der Controller mit maximaler Geschwindigkeit.&lt;br /&gt;
&lt;br /&gt;
Die Theorie wird durch folgendes Programm verifiziert. Der geviertelte System-Takt SYSCLK wir am Pin PC9 ausgegeben. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);&lt;br /&gt;
&lt;br /&gt;
    GPIO_InitTypeDef GPIOC_InitStructure;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Mode = GPIO_Mode_AF;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_OType = GPIO_OType_PP;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Pin = GPIO_Pin_9;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;&lt;br /&gt;
    GPIO_Init(GPIOC, &amp;amp;GPIOC_InitStructure);&lt;br /&gt;
&lt;br /&gt;
    RCC_MCO2Config(RCC_MCO2Source_SYSCLK, RCC_MCO2Div_4);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Die FPU===&lt;br /&gt;
====Allgemeines====&lt;br /&gt;
Damit die FPU richtig verwendet wird, müssen normalerweise zwei Bedingungen erfüllt sein:&lt;br /&gt;
&lt;br /&gt;
1. Der Controller muss in der Initialisierung-Funktion &#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; in &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; die FPU Hardware-seitig aktivieren&lt;br /&gt;
&lt;br /&gt;
2. Damit die FPU auch was zu tuen bekommt, müssen vom Compiler FPU-Instructions erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
Die Em::Blocks IDE verwendet standardmäßig die FPU, wenn eine Vorhanden ist. Hier wird die FPU Hardware-seitig aktiviert (&#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; Z.341):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* FPU settings ------------------------------------------------------------*/&lt;br /&gt;
  #if (__FPU_PRESENT == 1) &amp;amp;&amp;amp; (__FPU_USED == 1)&lt;br /&gt;
    SCB-&amp;gt;CPACR |= ((3UL &amp;lt;&amp;lt; 10*2)|(3UL &amp;lt;&amp;lt; 11*2));  /* set CP10 and CP11 Full Access */&lt;br /&gt;
  #endif&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
__FPU_PRESENT wird in der &#039;&#039;&#039;&#039;&#039;stm32f4xx.h&#039;&#039;&#039;&#039;&#039; definiert.&lt;br /&gt;
__FPU_USED wird von der IDE übernommen (siehe Build-Log): &#039;&#039;&#039;&#039;&#039;-D__FPU_USED&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Außerdem wird der Compiler von der IDE standardmäßig mit dem Argument &#039;&#039;&#039;&#039;&#039;-mfloat-abi=hard&#039;&#039;&#039;&#039;&#039; aufgerufen, wodurch FPU-Instructions erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
====FPU abschalten====&lt;br /&gt;
Um die FPU ab zu schalten (Mir würde jetzt nur Strom sparen als Grund einfallen) geht man wie folgt vor:&lt;br /&gt;
&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick Build options -&amp;gt; Device -&amp;gt; Policy&#039;&#039;&#039;&#039;&#039; wählt man &#039;&#039;&#039;&#039;&#039;Use target settings&#039;&#039;&#039;&#039;&#039; und über nimmt die Einstellungen, die vorher dort eingetragen waren, allerdings lässt man das Feld &#039;&#039;&#039;&#039;&#039;FP-hardware&#039;&#039;&#039;&#039;&#039; frei.&lt;br /&gt;
&lt;br /&gt;
[[Datei:fpu_1.png|FPU Abschalten Schritt 1]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;Compiler Settings -&amp;gt; Policy&#039;&#039;&#039;&#039;&#039; wählt man dann &#039;&#039;&#039;&#039;&#039;Use target options only&#039;&#039;&#039;&#039;&#039;. Dann kann man unter &#039;&#039;&#039;&#039;&#039;Categories&#039;&#039;&#039;&#039;&#039; die Option &#039;&#039;&#039;&#039;&#039;ARM FPU architecture&#039;&#039;&#039;&#039;&#039; auswählen. Dort stehen dann drei Möglichkeiten für die FPU zur Verfügung:&lt;br /&gt;
&lt;br /&gt;
1. Software-FPU-Library für Gleitkomma-Berechnung verwenden - Keine FPU-Instructions werden generiert (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=soft&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
2. Eine Mischung aus Software- und Hardware-FPU wird verwendet (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=softfp&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
3. Hardware-FPU wird für Gleitkomma-Berechnungen verwendet (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=hard&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
[[Datei:fpu_2.png|FPU Abschalten Schritt 2]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Um die FPU ab zu schalten wählt man natürlich die erste Möglichkeit.&lt;br /&gt;
Bei der 2. und 3. Möglichkeit fügt die IDE auch den Define &#039;&#039;&#039;&#039;&#039;__FPU_USED&#039;&#039;&#039;&#039;&#039; hinzu. Bei Der ersten Möglichkeit nicht. Der Code muss also nicht verändert / auskommentiert werden.&lt;br /&gt;
&lt;br /&gt;
Um die FPU wieder zu aktivieren müssen alle Schritte wieder rückgängig gemacht werden.&lt;br /&gt;
&lt;br /&gt;
Am besten ist es einfach mal alle Möglichkeiten im Einzelschritt durch zu probieren. Dann stellt man schnell fest, ob die FPU aktiviert wir oder nicht. Ein Blick in den erweiterten &#039;&#039;&#039;&#039;&#039;Build-Log&#039;&#039;&#039;&#039;&#039; gibt auch schnell Aufschluss darüber, wie der Compiler aufgerufen wird (siehe Kapitel [http://www.mikrocontroller.net/articles/STM32_-_Einstieg_mit_Em::Blocks#Compilieren Compilieren]).&lt;br /&gt;
&lt;br /&gt;
====Test Programm für die FPU====&lt;br /&gt;
Hier ein kleines Testprogramm, dass misst wie viele Taktzyklen für eine Gleitkomma-Multiplikation gebraucht werden. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define CORE_SysTickEn()    (*((u32*)0xE0001000)) = 0x40000001&lt;br /&gt;
#define CORE_SysTickDis()   (*((u32*)0xE0001000)) = 0x40000000&lt;br /&gt;
#define CORE_GetSysTick()   (*((u32*)0xE0001004))&lt;br /&gt;
&lt;br /&gt;
uint32_t t1, t2, dt;&lt;br /&gt;
float x, y, z;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    x = 53.64f;&lt;br /&gt;
    y = 0.27f;&lt;br /&gt;
&lt;br /&gt;
    CORE_SysTickEn();&lt;br /&gt;
    t1 = CORE_GetSysTick();&lt;br /&gt;
&lt;br /&gt;
    z = x * y;&lt;br /&gt;
&lt;br /&gt;
    t2 = CORE_GetSysTick();&lt;br /&gt;
    CORE_SysTickDis();&lt;br /&gt;
&lt;br /&gt;
    dt = t2 - t1;&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Compiler-Optimierung===&lt;br /&gt;
&lt;br /&gt;
==Booten aus dem SRAM==&lt;br /&gt;
STM32 Controller haben die Möglichkeit Code aus dem Flash als auch aus dem SRAM auszuführen. Um eine Anwenung per Debugger in des SRAM zu laden sind nur wenige Schritte erforderlich:&lt;br /&gt;
&lt;br /&gt;
*Um das Linkerscript für den SRAM zu verwenden geht man zu: &#039;&#039;&#039;&#039;&#039;Build options... -&amp;gt; Device&#039;&#039;&#039;&#039;&#039; dort wählt man unter &#039;&#039;&#039;&#039;&#039;Policy&#039;&#039;&#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;Use target settings&#039;&#039;&#039;&#039;&#039; aus und übernimmt die vorherigen Einstellungen, nur unter &#039;&#039;&#039;&#039;&#039;Linker script*&#039;&#039;&#039;&#039;&#039; gibt man &#039;&#039;&#039;&#039;&#039;.\stm32f407vg_sram.ld&#039;&#039;&#039;&#039;&#039; an&lt;br /&gt;
&lt;br /&gt;
*Dann muss man noch unter &#039;&#039;&#039;&#039;&#039;Debug -&amp;gt; Interfaces -&amp;gt; Settings&#039;&#039;&#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;Vector table start&#039;&#039;&#039;&#039;&#039; auf 0x20000000 ändern und &#039;&#039;&#039;&#039;&#039;Execute from RAM&#039;&#039;&#039;&#039;&#039; auswählen.&lt;br /&gt;
&lt;br /&gt;
Anschließend kann man die Anwendung ganz normal debuggen. Nach einem Reset muss die Anwenung erneut mit dem Debugger gestartet werden.&lt;br /&gt;
&lt;br /&gt;
=Fortsetzung folgt..=&lt;br /&gt;
Kritik, Wünsche usw. sind gerne erwünscht, am besten hier in den Thread posten: [http://www.mikrocontroller.net/topic/323750 Neues STM32 Tutorial]&lt;br /&gt;
&lt;br /&gt;
[[Category:ARM]]&lt;br /&gt;
[[Category:STM32]]&lt;/div&gt;</summary>
		<author><name>Avrprogger</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=STM32_-_Einstieg_mit_Em::Blocks&amp;diff=81518</id>
		<title>STM32 - Einstieg mit Em::Blocks</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=STM32_-_Einstieg_mit_Em::Blocks&amp;diff=81518"/>
		<updated>2014-02-10T21:09:52Z</updated>

		<summary type="html">&lt;p&gt;Avrprogger: dfgf&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In diesem Tutorial werde ich versuchen, möglichst einfach, die ersten Schritte zur Entwicklung von STM32 Anwenungen mit der Em::Blocks IDE zu erklären. Hier soll nicht so stark auf die einzelnen Peripherie-Module der Controller eingegangen werden, sondern mehr auf die IDE und die verschieden Libraries, wie die CMSIS Library, die DSP-Library, die Standard-Peripheral-Library, die USB-Library und vllt. über Ethernet. Ich denke ein Kapitel zu FreeRTOS wird es auch geben. Auserdem steht im Vordergrund Sachen wie z.B. booten aus dem SRAM, In-Application-Programming, FPU, Core-Coupled-RAM usw. Mal sehn wie weit ich komme ;)&lt;br /&gt;
&lt;br /&gt;
==Die Entwicklungsumgebung==&lt;br /&gt;
===Hardware===&lt;br /&gt;
Zum testen der Anwendungen, benutze ich das STM32F4-Discovery Board, welches einen Debugger, Peripherie und natürlich einen STM32 Controller (STM32F407VGT6) enthält. Deshalb sind alle Beispiele hier für den STM32F407VG Controller ausgelegt, können aber meisten 1:1 auf andere Controller portiert werden. Ich werde auch möglichsts keine STM32F4-Discovery Board spezifischen Libraries verwenden, damit der Portierungs-Vorgang möglichsts einfach bleibt.&lt;br /&gt;
&lt;br /&gt;
===Software===&lt;br /&gt;
In diesem Tutorial verwende ich [http://www.emblocks.org/ Em::Blocks] als IDE. Em::Blocks ist eine kostenlose, uneingeschränkte IDE, die alle STM32 Mikrcontroller unterstützt und sehr einfach zu bedienen ist.&lt;br /&gt;
nach dem Download kann die IDE per Dialog, sehr einfach, installiert werden. Als Compiler beinhaltet Em::Blocks den &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
Die IDE unterstützt zurzeit den ST-Link, den J-Link und es gibt eine Generic-Vorlage, durch welche andere Debugger konfiguriert werden können.&lt;br /&gt;
&lt;br /&gt;
Außerdem muss noch der passende Treiber für den Debugger installiert werden. Verwendet man ein Discovery-Board muss der [http://www.st.com/web/catalog/tools/FM146/CL1984/SC724/SS1677/PF251168 ST-Link/V2]-Treiber heruntergeladen und installiert werden. (Die Installation muss evtl. als Administrator ausgeführt werden, da sonst die Installation unvollständig wird.) Nach der Installation des Treibers kann man den Debugger über die entsprechende USB Schnittstelle an den PC anschließen und es sollte die Meldung von Windows kommen, dass der richtige Treiber gefunden wurde.&lt;br /&gt;
&lt;br /&gt;
===Libraries===&lt;br /&gt;
Zum programmieren benötigt man noch die [http://www.arm.com/products/processors/cortex-m/cortex-microcontroller-software-interface-standard.php CMSIS] und die Standard-Peripheral-Library (z.B. für die F4 Controller [http://www.st.com/stonline/stappl/productcatalog/app?page=partNumberSearchPage&amp;amp;levelid=SS1577&amp;amp;parentid=1743&amp;amp;resourcetype=SW Standard-Peripheral-Library-F4]), die man am besten in einen Ordner (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\STM32&#039;&#039;&#039;&#039;&#039;) entpackt&lt;br /&gt;
&lt;br /&gt;
==Basis-Wissen zur IDE==&lt;br /&gt;
Einige Grundfunktionalitäten der IDE:&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von Dateien zum Projekt===&lt;br /&gt;
Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf &amp;lt;ProjektName&amp;gt; -&amp;gt; Add files...&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Enfernen von Dateien aus dem Projekt===&lt;br /&gt;
Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf die Datei / mehrere Dateien auswählen -&amp;gt; Remove file from project&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
Die Dateien werden lediglich aus dem Projekt entfernt und nicht von der Festplatte gelöscht.&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von Include-Pfaden===&lt;br /&gt;
Sofern die Include-Datei(en) nicht im standard Include-Ordner &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; des Projektes liegen, muss man den Pfad zum Projekt hinzufügen, damit der Compiler die Include-Dateien später auch finden kann. Man geht wie folgt vor: Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf &amp;lt;ProjektName&amp;gt; -&amp;gt; Build options... -&amp;gt; Search Directories -&amp;gt; Add&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Compilieren===&lt;br /&gt;
Entweder über das &#039;&#039;&#039;&#039;&#039;Build&#039;&#039;&#039;&#039;&#039; Menü oder über &#039;&#039;&#039;&#039;&#039;F7&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Um eine genau Ausgabe des Compiler-Aufrufes mit allen Argumenten zu bekommen, geht man im &#039;&#039;&#039;&#039;&#039;Settings&#039;&#039;&#039;&#039;&#039; Menü auf &#039;&#039;&#039;&#039;&#039;Tools...&#039;&#039;&#039;&#039;&#039; und dann auf &#039;&#039;&#039;&#039;&#039;Toolchain executables&#039;&#039;&#039;&#039;&#039;. Ganz unten, unter &#039;&#039;&#039;&#039;&#039;Logging&#039;&#039;&#039;&#039;&#039; kann man dann &#039;&#039;&#039;&#039;&#039;Full command line&#039;&#039;&#039;&#039;&#039; auswählen.&lt;br /&gt;
&lt;br /&gt;
===Debuggen===&lt;br /&gt;
*Als erstes den Debugger starten über das &#039;&#039;&#039;&#039;&#039;Debug&#039;&#039;&#039;&#039;&#039; Menü und &#039;&#039;&#039;&#039;&#039;Start/stop Debug Session&#039;&#039;&#039;&#039;&#039; oder über &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
*Danach läuft die Anwendung auf dem Controller und warten im &#039;&#039;&#039;&#039;&#039;Reset_Handler&#039;&#039;&#039;&#039;&#039; auf Einzelschritt- bzw. Run- Befehle (&#039;&#039;&#039;&#039;&#039;F5, F10, F11&#039;&#039;&#039;&#039;&#039; usw..(siehe &#039;&#039;&#039;&#039;&#039;Debug-Menü&#039;&#039;&#039;&#039;&#039; für alle Möglichkeiten))&lt;br /&gt;
&lt;br /&gt;
*Mit &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039; wird die Debug-Session auch wieder beendet&lt;br /&gt;
&lt;br /&gt;
*Unter &#039;&#039;&#039;&#039;&#039;Debug -&amp;gt; Interfaces -&amp;gt; Target settings&#039;&#039;&#039;&#039;&#039; können Eigenschaften, wie z.B &#039;&#039;&#039;&#039;&#039;Run to main()&#039;&#039;&#039;&#039;&#039; aktiviert werden.&lt;br /&gt;
&lt;br /&gt;
===Projekt als Template abspeichern===&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;File -&amp;gt; Save project as template...&#039;&#039;&#039;&#039;&#039;. Das Template erscheint dann im Projekt-Dialog unter &#039;&#039;&#039;&#039;&#039;User templates&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Das erste Projekt erstellen==&lt;br /&gt;
Hier erkläre ich, wie man am Besten (aus meiner Sicht), ein neues Projekt von Grund auf erstellt, sodass man hinterher, den Controller-Kern über die CMSIS-Library und die Peripherie über die Register steuern kann.&lt;br /&gt;
&lt;br /&gt;
===1. Projekt mit der IDE erstellen===&lt;br /&gt;
Nach der Installation der oben beschriebenen Komponenten erstellt man am besten ein Verzeichnis (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\EmBlocks&#039;&#039;&#039;&#039;&#039;), indem später alle Projekte gespeichert werden. Für Libraries kann man auch noch ein Verzeichnis (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\STM32&#039;&#039;&#039;&#039;&#039;) erstellen, wo alle Libraries gespeichert werden, die man für die Projekt brauchen.&lt;br /&gt;
&lt;br /&gt;
Als nächstes starten man EmBlocks. Bei dem ersten Start öffnet sich ein Fenster, wo verschiedene Compiler angezeigt werden, die Em::Blocks findet. Dort wählt man den &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039; aus und klickt &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039;. Nun sollte sich das Hauptfenster von Em::Blocks öffnen. Über &#039;&#039;&#039;&#039;&#039;Create a new Project&#039;&#039;&#039;&#039;&#039; oder &#039;&#039;&#039;&#039;&#039;File -&amp;gt; New -&amp;gt; Project&#039;&#039;&#039;&#039;&#039; ruft man den Projekt-Dialog auf und kann ein neues Projekt erzeugen.&lt;br /&gt;
&lt;br /&gt;
Auf der Ersten Seite wählen man den &#039;&#039;&#039;&#039;&#039;STmicro-ARM&#039;&#039;&#039;&#039;&#039; Projekt-Typ aus.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_1.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auf der nächsten Seite wird man darauf hingewiesen, dass das der entsprechende Projekt-Typ-Dialog ausgeführt wird. Hier kann man ein Häkchen bei &#039;&#039;&#039;&#039;&#039;Skip this page next time&#039;&#039;&#039;&#039;&#039; setzen und auf &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; klicken.&lt;br /&gt;
&lt;br /&gt;
Im nächsten Schritt wählen man das zuvor erstellt Verzeichnis unter &#039;&#039;&#039;&#039;&#039;Folder to create Project in&#039;&#039;&#039;&#039;&#039; aus, indem später alle Projekt gespeichert werden. Außerdem geben wir dem Projekt einen Namen (z.B. &#039;&#039;&#039;&#039;&#039;FirstProject&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_2.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danach muss man einen Compiler auswählen und bestimmen, welche Projekt-Konfigurationen erszeugt werden sollen. Unter &#039;&#039;&#039;&#039;&#039;Compiler&#039;&#039;&#039;&#039;&#039; wählt man &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039; und man kann das Häkchen bei &#039;&#039;&#039;&#039;&#039;Create &amp;quot;Release&amp;quot; configuration&#039;&#039;&#039;&#039;&#039; entfernen, da diese unnötig ist, die Debug-Konfiguration sollte eig. immer ausreichen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_3.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auf den folgenden Seite wird der Controller ausgewählt. Verwendet man ein STM32F4-Discovery Board müssen folgende Dinge gewählt werden: &#039;&#039;&#039;&#039;&#039;Cortex_M4 (F3xx - F4xx) -&amp;gt; STM32F4xx (Cortex M4 with FPU) -&amp;gt; STM32F407VG&#039;&#039;&#039;&#039;&#039;. Leider sind die Auswahl Möglichkeiten nicht ganz richtig, da auch die F3 Controller einen Cortex M4 Kern und eine FPU haben (Ist aber nicht so wichtig, ist nur eine formale Sache). Außerdem entfernt man das Häkchen bei &#039;&#039;&#039;&#039;&#039;Standard Peripherals Library&#039;&#039;&#039;&#039;&#039; (Wie man die Standard-Peripheral-Library einbindet und verwendet erkläre ich später). Man kann auch das Häkchen bei &#039;&#039;&#039;&#039;&#039;Create hex file for Realease target&#039;&#039;&#039;&#039;&#039; entfernen.&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;Stack Size&#039;&#039;&#039;&#039;&#039; und &#039;&#039;&#039;&#039;&#039;Heap Size&#039;&#039;&#039;&#039;&#039; wird die Größe von Stack und Heap festgelegt. Für eine erste Anwendung kann man die Einstellungen so lassen (Stack-Size: 0x0100 =&amp;gt; 256 Byte Stack und Heap-Size: 0x0000 =&amp;gt; kein Heap). Mit &#039;&#039;&#039;&#039;&#039;Finish&#039;&#039;&#039;&#039;&#039; ist der Projekt Dialog abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_4.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danach sollten sich zwei neue Fenster öffnen, um die Debug-Eigenschaften fest zu legen.&lt;br /&gt;
Verwendet man ein Discovery Board/ST-Link müssen die Einstellungen wie auf dem Bild gewählt werden. Über den Button &#039;&#039;&#039;&#039;&#039;Settings&#039;&#039;&#039;&#039;&#039; öffnet sich das zweite Fenster, falls sich dieses nicht schon von alleine öffnen sollte. Nach den Schließen der Fenster über &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; ist der Projekt Dialog beendet und ein neues Projekt steht zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_5_1.png|Debug Eigenschaften 1. Fenster]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_5_2.png|Debug Eigenschaften 2. Fenster]]&lt;br /&gt;
&lt;br /&gt;
===2. CMSIS-Library und Startup-Code hinzufügen===&lt;br /&gt;
Wenn man sich, nachdem man ein neues Projekt in der IDE erstellt hat, die bereits vorhandenen Dateien im Projekt ansieht, stellt man fest, das bereits ein Ordner &#039;&#039;&#039;&#039;&#039;cmsis&#039;&#039;&#039;&#039;&#039; existiert, der einige wichtige Include-Dateien der CMSIS-Library enthält. Allerdings sind das wirklich nur die wichtigsten Include-Dateien der CMSIS-Library und dazu noch, die aus einer älternen Version. Ich ziehe es deshalb vor die &amp;quot;Mini-CMSIS-Libraray&amp;quot; und die &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c/.h&#039;&#039;&#039;&#039;&#039; Dateien des Projektes durch aktuellere Versionen zu ersetzen. So ist später auch die Integration  von anderen Libraries, wie z.B. der CMSIS-DSP-Libarary einfacher.  &lt;br /&gt;
&lt;br /&gt;
Zunächst gehen man in das Projekt-Verzeichnis und löscht:&lt;br /&gt;
*Den Ordner &#039;&#039;&#039;&#039;&#039;cmsis&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Alle Dateien im Include Verzeichnis &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; im &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner&lt;br /&gt;
&lt;br /&gt;
Außerdem entfernt man auch alle gelöschten Dateien in der IDE aus dem Projekt mit &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Rechts Klick -&amp;gt; Remove file from project&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Es sollte folgende Verzeichnis Struktur überbleiben:&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_6.png|Überbleibende Dateien]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Jetzt müssen die gelöschten Dateien durch die aktuelleren ersetzt werden.&lt;br /&gt;
&lt;br /&gt;
*Dazu kopieren man den gesamten Ordner &#039;&#039;&#039;&#039;&#039;CMSIS&#039;&#039;&#039;&#039;&#039; aus dem CMSIS Download in das Projekt Verzeichnis.&lt;br /&gt;
&lt;br /&gt;
*Aus dem Standard-Peripheral-Library Download kopiert man von &#039;&#039;&#039;&#039;&#039;Libraries\CMSIS\Device\ST\STM32F4xx\Include&#039;&#039;&#039;&#039;&#039; alle Dateien in den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projekt Verzeichnisses&lt;br /&gt;
&lt;br /&gt;
*Aus der Standard-Peripheral-Library kopieren man ebenfalls von &#039;&#039;&#039;&#039;&#039;Libraries\CMSIS\Device\ST\STM32F4xx\Source\Templates&#039;&#039;&#039;&#039;&#039; die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; in den &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner des Projekts&lt;br /&gt;
&lt;br /&gt;
Anschließend müssen die neuen Dateien in der IDE dem Projekt hinzugefügt werden. Dazu benutzt man &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Rechts Klick -&amp;gt; Add files&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
*Aus dem &#039;&#039;&#039;&#039;&#039;CMSIS&#039;&#039;&#039;&#039;&#039; Ordner im Projekt Verzeichnis werden aus den Unterorder &#039;&#039;&#039;&#039;&#039;Include&#039;&#039;&#039;&#039;&#039; folgende Dateien dem Projekt hinzugefügt:&lt;br /&gt;
**arm_common_tables.h&lt;br /&gt;
**arm_const_structs.h&lt;br /&gt;
**arm_math.h&lt;br /&gt;
**core_cm4.h&lt;br /&gt;
**core_cm4_simd.h&lt;br /&gt;
**core_cmFunc.h&lt;br /&gt;
**core_cmInstr.h&lt;br /&gt;
*Alle Dateien aus den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projektes&lt;br /&gt;
*Die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; aus dem &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner&lt;br /&gt;
&lt;br /&gt;
So sollte die Struktur dann aussehen:&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_7.png|Anwenungs-Grundgerüst]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Da einige Dateien der Libraries später bearbeitet werden müssen und Schreibgeschützt sind, weise ich hier schonmal darauf hin, das der Schreibschutz in der IDE über &#039;&#039;&#039;&#039;&#039;Rechts Klick auf die Datei -&amp;gt; Properties -&amp;gt; Häkchen bei &amp;quot;File is read only&amp;quot; entfernen&#039;&#039;&#039;&#039;&#039; entfert werden kann.&lt;br /&gt;
&lt;br /&gt;
Damit die IDE die Header-Dateien der CMSIS Library auch finden kann, weil diese ja nicht im standard Include Ordner &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; liegen, muss unter &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Build Options -&amp;gt; Search Directories&#039;&#039;&#039;&#039;&#039; der Pfad &#039;&#039;&#039;&#039;&#039;CMSIS\Include&#039;&#039;&#039;&#039;&#039; hinzugefügt werden.&lt;br /&gt;
&lt;br /&gt;
Compiliert man jetzt das Projekt mit &#039;&#039;&#039;&#039;&#039;F7&#039;&#039;&#039;&#039;&#039; gibt es ein paar Fehler Meldungen, weil keine Controller-Reihe ausgewählt wurde. Ebenfalls unter &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Build Options -&amp;gt; Compiler Settings -&amp;gt; #defines&#039;&#039;&#039;&#039;&#039; wird der Define &#039;&#039;&#039;&#039;&#039;STM32F40_41xxx&#039;&#039;&#039;&#039;&#039; hinzugefügt.&lt;br /&gt;
&lt;br /&gt;
Beim erneuten Compilieren sollten sich nun keine neuen Fehler ergeben.&lt;br /&gt;
&lt;br /&gt;
===Das erste Programm===&lt;br /&gt;
Nachdem ein grundsätzliches &amp;quot;Gerüst&amp;quot; fertig ist, kann man den ersten Code schreiben.&lt;br /&gt;
main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC-&amp;gt;AHB1ENR |= RCC_AHB1ENR_GPIODEN;    //Takt für GPIO aktivieren&lt;br /&gt;
    GPIOD-&amp;gt;MODER |= GPIO_MODER_MODER15_0;   //GPIOD Pin15 als Ausgang&lt;br /&gt;
    GPIOD-&amp;gt;BSRRL |= GPIO_BSRR_BS_15;        //GPIOD Pin15 auf High ziehen&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039; wird dann der Debugger gestartet. Hat der Debugger das Projekt erfolgreich übertragen kann die Ausführung mit &#039;&#039;&#039;&#039;&#039;F5&#039;&#039;&#039;&#039;&#039; begonnen werden.&lt;br /&gt;
&lt;br /&gt;
==Libraries einbinden/verwenden==&lt;br /&gt;
===Einbinden der Standard-Peripheral-Library===&lt;br /&gt;
Um nicht immer die einzelnen Register, wie im ersten &amp;quot;bare-metal&amp;quot; Beispiel, aus dem Reference-Manual zu suchen und zu beschreiben, gibt es von ST die Standard Peripheral Library, die diese Aufgaben übernimmt und mit der sich die &amp;quot;normale/grundlegende&amp;quot; (Alles außer USB und Ethernet) Peripherie recht einfach steuern lässt. Um die Library zu verwenden erzeugt man wie oben beschrieben ein neues Grundgerüst und kopiert als erstes den Ordner &#039;&#039;&#039;&#039;&#039;Libraries\STM32F4xx_StdPeriph_Driver&#039;&#039;&#039;&#039;&#039; aus dem Standard-Peripheral-Library Download in das Projekt-Verzeichnis. Außerdem muss man die Datei &#039;&#039;&#039;&#039;&#039;Project\STM32F4xx_StdPeriph_Templates\stm32f4xx_conf.h&#039;&#039;&#039;&#039;&#039; ebenfalls aus dem Standard-Peripheral-Library Download in den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projektes kopieren. In der IDE fügt man den Include-Path &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\inc&#039;&#039;&#039;&#039;&#039; hinzufügen, wie bei der CMSIS-Library (s.o.).&lt;br /&gt;
Außerdem muss noch &#039;&#039;&#039;&#039;&#039;USE_STDPERIPH_DRIVER&#039;&#039;&#039;&#039;&#039; als Define in der IDE hinzugefügt werden (s.o.).&lt;br /&gt;
Danach fügt man die Source- und Include-Dateien aus dem Ordner &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\inc&#039;&#039;&#039;&#039;&#039; und &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\src&#039;&#039;&#039;&#039;&#039; dem Project mit &#039;&#039;&#039;&#039;&#039;&amp;lt;Project Name&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Add files&#039;&#039;&#039;&#039;&#039; hinzu, allerdings nur die, für welche auch der Controller die entsprechende Peripherie besitzt. Beim STM32F4-Discovery Board / STM32F407VG Controller dürfen also nicht folgende Dateien nicht mit hinzugefügt werden, weil diese Peripherie nur bei anderen Controller vorhanden ist:&lt;br /&gt;
&lt;br /&gt;
*stm32f4xx_dma2d.c/.h&lt;br /&gt;
*stm32f4xx_fmc.c/.h&lt;br /&gt;
*stm32f4xx_ltdc.c/.h&lt;br /&gt;
*stm32f4xx_sai.c/.h&lt;br /&gt;
&lt;br /&gt;
Daraus resultiert folgende Struktur:&lt;br /&gt;
&lt;br /&gt;
[[Datei:stdperiphlib_2.png|Header-Struktur]] [[Datei:stdperiphlib_1.png|Source-Struktur]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Anschließen kann die Standard-Peripheral-Library benutz werden.&lt;br /&gt;
main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);&lt;br /&gt;
&lt;br /&gt;
    GPIO_InitTypeDef GPIOD_InitStructure;&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Mode = GPIO_Mode_OUT;     //Als Ausgang&lt;br /&gt;
    GPIOD_InitStructure.GPIO_OType = GPIO_OType_PP;    //Push-Pull Betrieb&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Pin = GPIO_Pin_15;        //Pin 15 (STM32F4-Discovery: Blaue LED)&lt;br /&gt;
    GPIOD_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;  //Kein Pull-Up oder Pull-Down Widerstand aktiviert&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Speed = GPIO_Speed_25MHz; //25MHz Update-Rate&lt;br /&gt;
    GPIO_Init(GPIOD, &amp;amp;GPIOD_InitStructure);&lt;br /&gt;
&lt;br /&gt;
    GPIO_SetBits(GPIOD, GPIO_Pin_15);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Startup-Code, Linker-Script, Takt, FPU usw.==&lt;br /&gt;
===Startup-Code===&lt;br /&gt;
Em::Blocks fügt standardmäßig einen Startup-Code mit in das Projekt ein. Die wichtigsten Dinge die darin erledigt werden sind folgende:&lt;br /&gt;
&lt;br /&gt;
*Stack und Heap wird angelgt&lt;br /&gt;
*Die Vector-Table wird angelegt&lt;br /&gt;
*Ein Default Reset-Handler wird implementiert, dieser erledigt folgende aufgaben:&lt;br /&gt;
**Kopieren der definierten Daten aus dem Flash in den SRAM&lt;br /&gt;
**&#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; wird aufgerfen, wenn &#039;&#039;&#039;&#039;&#039;__NO_SYSTEM_INIT&#039;&#039;&#039;&#039;&#039; nicht definiert ist&lt;br /&gt;
**Sprung in die &#039;&#039;&#039;&#039;&#039;main()&#039;&#039;&#039;&#039;&#039; Funktion&lt;br /&gt;
*Allen anderen Interrupt-Handler wird eine Default-Funktion &#039;&#039;&#039;&#039;&#039;def_irq_handler&#039;&#039;&#039;&#039;&#039; mit einer &#039;&#039;&#039;&#039;&#039;while(1)&#039;&#039;&#039;&#039;&#039;-Schleife zugewiesen, falls kein anderer Interrupt-Handler existiert.&lt;br /&gt;
&lt;br /&gt;
Normalerweise muss am Startup-Code nichts verändert werden.&lt;br /&gt;
&lt;br /&gt;
===Linker-Script===&lt;br /&gt;
Em::Blocks stellt zwei fertige Linker-Scripts bereit, eins für die Ausführung des Programmes aus dem Flash (&#039;&#039;&#039;&#039;&#039;*_flash.ld&#039;&#039;&#039;&#039;&#039;), das andere für die Ausführung aus dem SRAM (&#039;&#039;&#039;&#039;&#039;*_sram.ld&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Normalerweise muss auch hier nichts geändert werden, es sei den Daten sollen in bestimmten Adressbereichen abgelegt werden (z.B. im Core-Coupled RAM), was ich später noch zum Tutorial hinzufüge.&lt;br /&gt;
&lt;br /&gt;
===Der Takt===&lt;br /&gt;
Jeder Controller oder Prozessor braucht einen Takt, indem er die einzelnen Maschinen-Befehle abarbeiten kann.&lt;br /&gt;
Bei den STM32 Mikrocontrollern kann dieser Takt aus verschiedenen Quellen kommen:&lt;br /&gt;
&lt;br /&gt;
1. High Speed Internal Oszillator (HSI)&lt;br /&gt;
&lt;br /&gt;
2. High Speed External Oszillator (HSE)&lt;br /&gt;
&lt;br /&gt;
3. Low Speed Internal Oszillator (LSI)&lt;br /&gt;
&lt;br /&gt;
4. Low Speed External Oszillator (LSE)&lt;br /&gt;
&lt;br /&gt;
5. Phase-Locked Loop (PLL) (generiert den Takt aus den ersten vier Taktquellen durch Teiler und Faktoren)&lt;br /&gt;
&lt;br /&gt;
Nach einem Reset wird der Controller aus der HSI Taktquelle versorgt (16MHz beim STM32F407VG). Um die voll Performance des Controllers zu erreichen muss die PLL verwendet werden, welche den Takt durch geschickte Teiler und Faktoren vervielfältigt, sodass am Ende der Controller mit der maximalen Taktfrequenz läuft. Die notwendige Initialisierung der PLL findet in der Funktion &#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; statt. Die PLL erzeugt zunächst einen Basistakt:&lt;br /&gt;
&lt;br /&gt;
PLL_VCO = (F_HSE / PLL_M) * PLL_N&lt;br /&gt;
&lt;br /&gt;
Aus diesem Takt wird dann der Takt für den Controller-Kern abgeleitet:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = PLL_VCO / PLL_P&lt;br /&gt;
&lt;br /&gt;
Und der Takt für SDIO / USB / RNG (48MHz):&lt;br /&gt;
&lt;br /&gt;
48MHz = PLL_VCO / PLL_Q&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Durch weiter Teiler werden, die Takte für die einzelnen Busse erzeugt, da diese nicht alle beliebig schnell betrieben werden dürfen.&lt;br /&gt;
&lt;br /&gt;
Genaue Angaben findet man zu dem jeweiligen Clock-System des Controllers im Reference Manual.&lt;br /&gt;
&lt;br /&gt;
Ein Blick in den &amp;quot;Kommentar-Header&amp;quot; verrät, dass von einem externen (HSE) Oszillator von 25MHz ausgegangen wird, der die PLL versorgen soll.&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((25MHz / PLL_M(25)) * PLL_N(336)) / PLL_P(2) = 168MHz&lt;br /&gt;
&lt;br /&gt;
Allerdings stimmt diese Rechnung natürlich nur, wenn wirklich ein 25MHz Quarz am Controller angeschlossen ist. Auf dem STM32F4-Discovery Board befindet sich aber nur ein 8MHz Quarz. Demnach gilt:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((8MHz / PLL_M(25)) * PLL_N(336)) / PLL_P(2) = 53.76MHz&lt;br /&gt;
&lt;br /&gt;
Der Controller läuft also nur mit 53.76MHz, wenn wie ober beschrieben ein Projekt erstellt wird. Allerdings kann dieses Problem durch ändern von den betroffen Defines behoben werden:&lt;br /&gt;
 &lt;br /&gt;
*Dazu geht man in die &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; Datei und passt zur Vollständigkeit erstmal die zum Controller passende Tabelle im &amp;quot;Kommentar-Header&amp;quot; an (Z.57f):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      HSE Frequency(Hz)                      | 8000000&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      PLL_M                                  | 8&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Danach passt man den PPL_M Define (Z.254) an:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/************************* PLL Parameters *************************************/&lt;br /&gt;
/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */&lt;br /&gt;
#define PLL_M      8&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Außerdem muss man den HSE_VALUE Define in der &#039;&#039;&#039;&#039;&#039;inc/stm32f4xx.h&#039;&#039;&#039;&#039;&#039; angepasst werden (Z.122):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#if !defined  (HSE_VALUE)&lt;br /&gt;
  #define HSE_VALUE    ((uint32_t)8000000) /*!&amp;lt; Value of the External oscillator in Hz */&lt;br /&gt;
&lt;br /&gt;
#endif /* HSE_VALUE */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine neue Berechnung zeigt:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((8MHz / PLL_M(8)) * PLL_N(336)) / PLL_P(2) = 168MHz&lt;br /&gt;
&lt;br /&gt;
Jetzt läuft der Controller mit maximaler Geschwindigkeit.&lt;br /&gt;
&lt;br /&gt;
Die Theorie wird durch folgendes Programm verifiziert. Der geviertelte System-Takt SYSCLK wir am Pin PC9 ausgegeben. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);&lt;br /&gt;
&lt;br /&gt;
    GPIO_InitTypeDef GPIOC_InitStructure;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Mode = GPIO_Mode_AF;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_OType = GPIO_OType_PP;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Pin = GPIO_Pin_9;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;&lt;br /&gt;
    GPIO_Init(GPIOC, &amp;amp;GPIOC_InitStructure);&lt;br /&gt;
&lt;br /&gt;
    RCC_MCO2Config(RCC_MCO2Source_SYSCLK, RCC_MCO2Div_4);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Die FPU===&lt;br /&gt;
====Allgemeines====&lt;br /&gt;
Damit die FPU richtig verwendet wird, müssen normalerweise zwei Bedingungen erfüllt sein:&lt;br /&gt;
&lt;br /&gt;
1. Der Controller muss in der Initialisierung-Funktion &#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; in &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; die FPU Hardware-seitig aktivieren&lt;br /&gt;
&lt;br /&gt;
2. Damit die FPU auch was zu tuen bekommt, müssen vom Compiler FPU-Instructions erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
Die Em::Blocks IDE verwendet standardmäßig die FPU, wenn eine Vorhanden ist. Hier wird die FPU Hardware-seitig aktiviert (&#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; Z.341):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* FPU settings ------------------------------------------------------------*/&lt;br /&gt;
  #if (__FPU_PRESENT == 1) &amp;amp;&amp;amp; (__FPU_USED == 1)&lt;br /&gt;
    SCB-&amp;gt;CPACR |= ((3UL &amp;lt;&amp;lt; 10*2)|(3UL &amp;lt;&amp;lt; 11*2));  /* set CP10 and CP11 Full Access */&lt;br /&gt;
  #endif&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
__FPU_PRESENT wird in der &#039;&#039;&#039;&#039;&#039;stm32f4xx.h&#039;&#039;&#039;&#039;&#039; definiert.&lt;br /&gt;
__FPU_USED wird von der IDE übernommen (siehe Build-Log): &#039;&#039;&#039;&#039;&#039;-D__FPU_USED&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Außerdem wird der Compiler von der IDE standardmäßig mit dem Argument &#039;&#039;&#039;&#039;&#039;-mfloat-abi=hard&#039;&#039;&#039;&#039;&#039; aufgerufen, wodurch FPU-Instructions erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
====FPU abschalten====&lt;br /&gt;
Um die FPU ab zu schalten (Mir würde jetzt nur Strom sparen als Grund einfallen) geht man wie folgt vor:&lt;br /&gt;
&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick Build options -&amp;gt; Device -&amp;gt; Policy&#039;&#039;&#039;&#039;&#039; wählt man &#039;&#039;&#039;&#039;&#039;Use target settings&#039;&#039;&#039;&#039;&#039; und über nimmt die Einstellungen, die vorher dort eingetragen waren, allerdings lässt man das Feld &#039;&#039;&#039;&#039;&#039;FP-hardware&#039;&#039;&#039;&#039;&#039; frei.&lt;br /&gt;
&lt;br /&gt;
[[Datei:fpu_1.png|FPU Abschalten Schritt 1]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;Compiler Settings -&amp;gt; Policy&#039;&#039;&#039;&#039;&#039; wählt man dann &#039;&#039;&#039;&#039;&#039;Use target options only&#039;&#039;&#039;&#039;&#039;. Dann kann man unter &#039;&#039;&#039;&#039;&#039;Categories&#039;&#039;&#039;&#039;&#039; die Option &#039;&#039;&#039;&#039;&#039;ARM FPU architecture&#039;&#039;&#039;&#039;&#039; auswählen. Dort stehen dann drei Möglichkeiten für die FPU zur Verfügung:&lt;br /&gt;
&lt;br /&gt;
1. Software-FPU-Library für Gleitkomma-Berechnung verwenden - Keine FPU-Instructions werden generiert (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=soft&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
2. Eine Mischung aus Software- und Hardware-FPU wird verwendet (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=softfp&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
3. Hardware-FPU wird für Gleitkomma-Berechnungen verwendet (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=hard&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
[[Datei:fpu_2.png|FPU Abschalten Schritt 2]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Um die FPU ab zu schalten wählt man natürlich die erste Möglichkeit.&lt;br /&gt;
Bei der 2. und 3. Möglichkeit fügt die IDE auch den Define &#039;&#039;&#039;&#039;&#039;__FPU_USED&#039;&#039;&#039;&#039;&#039; hinzu. Bei Der ersten Möglichkeit nicht. Der Code muss also nicht verändert / auskommentiert werden.&lt;br /&gt;
&lt;br /&gt;
Um die FPU wieder zu aktivieren müssen alle Schritte wieder rückgängig gemacht werden.&lt;br /&gt;
&lt;br /&gt;
Am besten ist es einfach mal alle Möglichkeiten im Einzelschritt durch zu probieren. Dann stellt man schnell fest, ob die FPU aktiviert wir oder nicht. Ein Blick in den erweiterten &#039;&#039;&#039;&#039;&#039;Build-Log&#039;&#039;&#039;&#039;&#039; gibt auch schnell Aufschluss darüber, wie der Compiler aufgerufen wird (siehe Kapitel [http://www.mikrocontroller.net/articles/STM32_-_Einstieg_mit_Em::Blocks#Compilieren Compilieren]).&lt;br /&gt;
&lt;br /&gt;
====Test Programm für die FPU====&lt;br /&gt;
Hier ein kleines Testprogramm, dass misst wie viele Taktzyklen für eine Gleitkomma-Multiplikation gebraucht werden. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define CORE_SysTickEn()    (*((u32*)0xE0001000)) = 0x40000001&lt;br /&gt;
#define CORE_SysTickDis()   (*((u32*)0xE0001000)) = 0x40000000&lt;br /&gt;
#define CORE_GetSysTick()   (*((u32*)0xE0001004))&lt;br /&gt;
&lt;br /&gt;
uint32_t t1, t2, dt;&lt;br /&gt;
float x, y, z;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    x = 53.64f;&lt;br /&gt;
    y = 0.27f;&lt;br /&gt;
&lt;br /&gt;
    CORE_SysTickEn();&lt;br /&gt;
    t1 = CORE_GetSysTick();&lt;br /&gt;
&lt;br /&gt;
    z = x * y;&lt;br /&gt;
&lt;br /&gt;
    t2 = CORE_GetSysTick();&lt;br /&gt;
    CORE_SysTickDis();&lt;br /&gt;
&lt;br /&gt;
    dt = t2 - t1;&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Booten aus dem SRAM==&lt;br /&gt;
STM32 Controller haben die Möglichkeit Code aus dem Flash als auch aus dem SRAM auszuführen. Um eine Anwenung per Debugger in des SRAM zu laden sind nur wenige Schritte erforderlich:&lt;br /&gt;
&lt;br /&gt;
*Um das Linkerscript für den SRAM zu verwenden geht man zu: &#039;&#039;&#039;&#039;&#039;Build options... -&amp;gt; Device&#039;&#039;&#039;&#039;&#039; dort wählt man unter &#039;&#039;&#039;&#039;&#039;Policy&#039;&#039;&#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;Use target settings&#039;&#039;&#039;&#039;&#039; aus und übernimmt die vorherigen Einstellungen, nur unter &#039;&#039;&#039;&#039;&#039;Linker script*&#039;&#039;&#039;&#039;&#039; gibt man &#039;&#039;&#039;&#039;&#039;.\stm32f407vg_sram.ld&#039;&#039;&#039;&#039;&#039; an&lt;br /&gt;
&lt;br /&gt;
*Dann muss man noch unter &#039;&#039;&#039;&#039;&#039;Debug -&amp;gt; Interfaces -&amp;gt; Settings&#039;&#039;&#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;Vector table start&#039;&#039;&#039;&#039;&#039; auf 0x20000000 ändern und &#039;&#039;&#039;&#039;&#039;Execute from RAM&#039;&#039;&#039;&#039;&#039; auswählen.&lt;br /&gt;
&lt;br /&gt;
Anschließend kann man die Anwendung ganz normal debuggen. Nach einem Reset muss die Anwenung erneut mit dem Debugger gestartet werden.&lt;br /&gt;
&lt;br /&gt;
=Fortsetzung folgt..=&lt;br /&gt;
Kritik, Wünsche usw. sind gerne erwünscht, am besten hier in den Thread posten: [http://www.mikrocontroller.net/topic/323750 Neues STM32 Tutorial]&lt;br /&gt;
&lt;br /&gt;
[[Category:ARM]]&lt;br /&gt;
[[Category:STM32]]&lt;/div&gt;</summary>
		<author><name>Avrprogger</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=STM32_-_Einstieg_mit_Em::Blocks&amp;diff=81515</id>
		<title>STM32 - Einstieg mit Em::Blocks</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=STM32_-_Einstieg_mit_Em::Blocks&amp;diff=81515"/>
		<updated>2014-02-10T16:55:02Z</updated>

		<summary type="html">&lt;p&gt;Avrprogger: ghj&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In diesem Tutorial werde ich versuchen, möglichst einfach, die ersten Schritte zur Entwicklung von STM32 Anwenungen mit der Em::Blocks IDE zu erklären. Hier soll nicht so stark auf die einzelnen Peripherie-Module der Controller eingegangen werden, sondern mehr auf die IDE und die verschieden Libraries, wie die CMSIS Library, die DSP-Library, die Standard-Peripheral-Library, die USB-Library und vllt. über Ethernet. Ich denke ein Kapitel zu FreeRTOS wird es auch geben. Auserdem steht im Vordergrund Sachen wie z.B. booten aus dem SRAM, In-Application-Programming, FPU, Core-Coupled-RAM usw. Mal sehn wie weit ich komme ;)&lt;br /&gt;
&lt;br /&gt;
==Die Entwicklungsumgebung==&lt;br /&gt;
===Hardware===&lt;br /&gt;
Zum testen der Anwendungen, benutze ich das STM32F4-Discovery Board, welches einen Debugger, Peripherie und natürlich einen STM32 Controller (STM32F407VGT6) enthält. Deshalb sind alle Beispiele hier für den STM32F407VG Controller ausgelegt, können aber meisten 1:1 auf andere Controller portiert werden. Ich werde auch möglichsts keine STM32F4-Discovery Board spezifischen Libraries verwenden, damit der Portierungs-Vorgang möglichsts einfach bleibt.&lt;br /&gt;
&lt;br /&gt;
===Software===&lt;br /&gt;
In diesem Tutorial verwende ich [http://www.emblocks.org/ Em::Blocks] als IDE. Em::Blocks ist eine kostenlose, uneingeschränkte IDE, die alle STM32 Mikrcontroller unterstützt und sehr einfach zu bedienen ist.&lt;br /&gt;
nach dem Download kann die IDE per Dialog, sehr einfach, installiert werden. Als Compiler beinhaltet Em::Blocks den &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
Die IDE unterstützt zurzeit den ST-Link, den J-Link und es gibt eine Generic-Vorlage, durch welche andere Debugger konfiguriert werden können.&lt;br /&gt;
&lt;br /&gt;
Außerdem muss noch der passende Treiber für den Debugger installiert werden. Verwendet man ein Discovery-Board muss der [http://www.st.com/web/catalog/tools/FM146/CL1984/SC724/SS1677/PF251168 ST-Link/V2]-Treiber heruntergeladen und installiert werden. (Die Installation muss evtl. als Administrator ausgeführt werden, da sonst die Installation unvollständig wird.) Nach der Installation des Treibers kann man den Debugger über die entsprechende USB Schnittstelle an den PC anschließen und es sollte die Meldung von Windows kommen, dass der richtige Treiber gefunden wurde.&lt;br /&gt;
&lt;br /&gt;
===Libraries===&lt;br /&gt;
Zum programmieren benötigt man noch die [http://www.arm.com/products/processors/cortex-m/cortex-microcontroller-software-interface-standard.php CMSIS] und die Standard-Peripheral-Library (z.B. für die F4 Controller [http://www.st.com/stonline/stappl/productcatalog/app?page=partNumberSearchPage&amp;amp;levelid=SS1577&amp;amp;parentid=1743&amp;amp;resourcetype=SW Standard-Peripheral-Library-F4]), die man am besten in einen Ordner (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\STM32&#039;&#039;&#039;&#039;&#039;) entpackt&lt;br /&gt;
&lt;br /&gt;
==Basis-Wissen zur IDE==&lt;br /&gt;
Einige Grundfunktionalitäten der IDE:&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von Dateien zum Projekt===&lt;br /&gt;
Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf &amp;lt;ProjektName&amp;gt; -&amp;gt; Add files...&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Enfernen von Dateien aus dem Projekt===&lt;br /&gt;
Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf die Datei / mehrere Dateien auswählen -&amp;gt; Remove file from project&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
Die Dateien werden lediglich aus dem Projekt entfernt und nicht von der Festplatte gelöscht.&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von Include-Pfaden===&lt;br /&gt;
Sofern die Include-Datei(en) nicht im standard Include-Ordner &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; des Projektes liegen, muss man den Pfad zum Projekt hinzufügen, damit der Compiler die Include-Dateien später auch finden kann. Man geht wie folgt vor: Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf &amp;lt;ProjektName&amp;gt; -&amp;gt; Build options... -&amp;gt; Search Directories -&amp;gt; Add&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Compilieren===&lt;br /&gt;
Entweder über das &#039;&#039;&#039;&#039;&#039;Build&#039;&#039;&#039;&#039;&#039; Menü oder über &#039;&#039;&#039;&#039;&#039;F7&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Um eine genau Ausgabe des Compiler-Aufrufes mit allen Argumenten zu bekommen, geht man im &#039;&#039;&#039;&#039;&#039;Settings&#039;&#039;&#039;&#039;&#039; Menü auf &#039;&#039;&#039;&#039;&#039;Tools...&#039;&#039;&#039;&#039;&#039; und dann auf &#039;&#039;&#039;&#039;&#039;Toolchain executables&#039;&#039;&#039;&#039;&#039;. Ganz unten, unter &#039;&#039;&#039;&#039;&#039;Logging&#039;&#039;&#039;&#039;&#039; kann man dann &#039;&#039;&#039;&#039;&#039;Full command line&#039;&#039;&#039;&#039;&#039; auswählen.&lt;br /&gt;
&lt;br /&gt;
===Debuggen===&lt;br /&gt;
*Als erstes den Debugger starten über das &#039;&#039;&#039;&#039;&#039;Debug&#039;&#039;&#039;&#039;&#039; Menü und &#039;&#039;&#039;&#039;&#039;Start/stop Debug Session&#039;&#039;&#039;&#039;&#039; oder über &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
*Danach läuft die Anwendung auf dem Controller und warten im &#039;&#039;&#039;&#039;&#039;Reset_Handler&#039;&#039;&#039;&#039;&#039; auf Einzelschritt- bzw. Run- Befehle (&#039;&#039;&#039;&#039;&#039;F5, F10, F11&#039;&#039;&#039;&#039;&#039; usw..(siehe &#039;&#039;&#039;&#039;&#039;Debug-Menü&#039;&#039;&#039;&#039;&#039; für alle Möglichkeiten))&lt;br /&gt;
&lt;br /&gt;
*Mit &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039; wird die Debug-Session auch wieder beendet&lt;br /&gt;
&lt;br /&gt;
*Unter &#039;&#039;&#039;&#039;&#039;Debug -&amp;gt; Interfaces -&amp;gt; Target settings&#039;&#039;&#039;&#039;&#039; können Eigenschaften, wie z.B &#039;&#039;&#039;&#039;&#039;Run to main()&#039;&#039;&#039;&#039;&#039; aktiviert werden.&lt;br /&gt;
&lt;br /&gt;
===Projekt als Template abspeichern===&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;File -&amp;gt; Save project as template...&#039;&#039;&#039;&#039;&#039;. Das Template erscheint dann im Projekt-Dialog unter &#039;&#039;&#039;&#039;&#039;User templates&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Das erste Projekt erstellen==&lt;br /&gt;
Hier erkläre ich, wie man am Besten (aus meiner Sicht), ein neues Projekt von Grund auf erstellt, sodass man hinterher, den Controller-Kern über die CMSIS-Library und die Peripherie über die Register steuern kann.&lt;br /&gt;
&lt;br /&gt;
===1. Projekt mit der IDE erstellen===&lt;br /&gt;
Nach der Installation der oben beschriebenen Komponenten erstellt man am besten ein Verzeichnis (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\EmBlocks&#039;&#039;&#039;&#039;&#039;), indem später alle Projekte gespeichert werden. Für Libraries kann man auch noch ein Verzeichnis (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\STM32&#039;&#039;&#039;&#039;&#039;) erstellen, wo alle Libraries gespeichert werden, die man für die Projekt brauchen.&lt;br /&gt;
&lt;br /&gt;
Als nächstes starten man EmBlocks. Bei dem ersten Start öffnet sich ein Fenster, wo verschiedene Compiler angezeigt werden, die Em::Blocks findet. Dort wählt man den &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039; aus und klickt &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039;. Nun sollte sich das Hauptfenster von Em::Blocks öffnen. Über &#039;&#039;&#039;&#039;&#039;Create a new Project&#039;&#039;&#039;&#039;&#039; oder &#039;&#039;&#039;&#039;&#039;File -&amp;gt; New -&amp;gt; Project&#039;&#039;&#039;&#039;&#039; ruft man den Projekt-Dialog auf und kann ein neues Projekt erzeugen.&lt;br /&gt;
&lt;br /&gt;
Auf der Ersten Seite wählen man den &#039;&#039;&#039;&#039;&#039;STmicro-ARM&#039;&#039;&#039;&#039;&#039; Projekt-Typ aus.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_1.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auf der nächsten Seite wird man darauf hingewiesen, dass das der entsprechende Projekt-Typ-Dialog ausgeführt wird. Hier kann man ein Häkchen bei &#039;&#039;&#039;&#039;&#039;Skip this page next time&#039;&#039;&#039;&#039;&#039; setzen und auf &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; klicken.&lt;br /&gt;
&lt;br /&gt;
Im nächsten Schritt wählen man das zuvor erstellt Verzeichnis unter &#039;&#039;&#039;&#039;&#039;Folder to create Project in&#039;&#039;&#039;&#039;&#039; aus, indem später alle Projekt gespeichert werden. Außerdem geben wir dem Projekt einen Namen (z.B. &#039;&#039;&#039;&#039;&#039;FirstProject&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_2.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danach muss man einen Compiler auswählen und bestimmen, welche Projekt-Konfigurationen erszeugt werden sollen. Unter &#039;&#039;&#039;&#039;&#039;Compiler&#039;&#039;&#039;&#039;&#039; wählt man &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039; und man kann das Häkchen bei &#039;&#039;&#039;&#039;&#039;Create &amp;quot;Release&amp;quot; configuration&#039;&#039;&#039;&#039;&#039; entfernen, da diese unnötig ist, die Debug-Konfiguration sollte eig. immer ausreichen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_3.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auf den folgenden Seite wird der Controller ausgewählt. Verwendet man ein STM32F4-Discovery Board müssen folgende Dinge gewählt werden: &#039;&#039;&#039;&#039;&#039;Cortex_M4 (F3xx - F4xx) -&amp;gt; STM32F4xx (Cortex M4 with FPU) -&amp;gt; STM32F407VG&#039;&#039;&#039;&#039;&#039;. Leider sind die Auswahl Möglichkeiten nicht ganz richtig, da auch die F3 Controller einen Cortex M4 Kern und eine FPU haben (Ist aber nicht so wichtig, ist nur eine formale Sache). Außerdem entfernt man das Häkchen bei &#039;&#039;&#039;&#039;&#039;Standard Peripherals Library&#039;&#039;&#039;&#039;&#039; (Wie man die Standard-Peripheral-Library einbindet und verwendet erkläre ich später). Man kann auch das Häkchen bei &#039;&#039;&#039;&#039;&#039;Create hex file for Realease target&#039;&#039;&#039;&#039;&#039; entfernen.&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;Stack Size&#039;&#039;&#039;&#039;&#039; und &#039;&#039;&#039;&#039;&#039;Heap Size&#039;&#039;&#039;&#039;&#039; wird die Größe von Stack und Heap festgelegt. Für eine erste Anwendung kann man die Einstellungen so lassen (Stack-Size: 0x0100 =&amp;gt; 256 Byte Stack und Heap-Size: 0x0000 =&amp;gt; kein Heap). Mit &#039;&#039;&#039;&#039;&#039;Finish&#039;&#039;&#039;&#039;&#039; ist der Projekt Dialog abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_4.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danach sollten sich zwei neue Fenster öffnen, um die Debug-Eigenschaften fest zu legen.&lt;br /&gt;
Verwendet man ein Discovery Board/ST-Link müssen die Einstellungen wie auf dem Bild gewählt werden. Über den Button &#039;&#039;&#039;&#039;&#039;Settings&#039;&#039;&#039;&#039;&#039; öffnet sich das zweite Fenster, falls sich dieses nicht schon von alleine öffnen sollte. Nach den Schließen der Fenster über &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; ist der Projekt Dialog beendet und ein neues Projekt steht zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_5_1.png|Debug Eigenschaften 1. Fenster]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_5_2.png|Debug Eigenschaften 2. Fenster]]&lt;br /&gt;
&lt;br /&gt;
===2. CMSIS-Library und Startup-Code hinzufügen===&lt;br /&gt;
Wenn man sich, nachdem man ein neues Projekt in der IDE erstellt hat, die bereits vorhandenen Dateien im Projekt ansieht, stellt man fest, das bereits ein Ordner &#039;&#039;&#039;&#039;&#039;cmsis&#039;&#039;&#039;&#039;&#039; existiert, der einige wichtige Include-Dateien der CMSIS-Library enthält. Allerdings sind das wirklich nur die wichtigsten Include-Dateien der CMSIS-Library und dazu noch, die aus einer älternen Version. Ich ziehe es deshalb vor die &amp;quot;Mini-CMSIS-Libraray&amp;quot; und die &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c/.h&#039;&#039;&#039;&#039;&#039; Dateien des Projektes durch aktuellere Versionen zu ersetzen. So ist später auch die Integration  von anderen Libraries, wie z.B. der CMSIS-DSP-Libarary einfacher.  &lt;br /&gt;
&lt;br /&gt;
Zunächst gehen man in das Projekt-Verzeichnis und löscht:&lt;br /&gt;
*Den Ordner &#039;&#039;&#039;&#039;&#039;cmsis&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Alle Dateien im Include Verzeichnis &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; im &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner&lt;br /&gt;
&lt;br /&gt;
Außerdem entfernt man auch alle gelöschten Dateien in der IDE aus dem Projekt mit &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Rechts Klick -&amp;gt; Remove file from project&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Es sollte folgende Verzeichnis Struktur überbleiben:&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_6.png|Überbleibende Dateien]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Jetzt müssen die gelöschten Dateien durch die aktuelleren ersetzt werden.&lt;br /&gt;
&lt;br /&gt;
*Dazu kopieren man den gesamten Ordner &#039;&#039;&#039;&#039;&#039;CMSIS&#039;&#039;&#039;&#039;&#039; aus dem CMSIS Download in das Projekt Verzeichnis.&lt;br /&gt;
&lt;br /&gt;
*Aus dem Standard-Peripheral-Library Download kopiert man von &#039;&#039;&#039;&#039;&#039;Libraries\CMSIS\Device\ST\STM32F4xx\Include&#039;&#039;&#039;&#039;&#039; alle Dateien in den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projekt Verzeichnisses&lt;br /&gt;
&lt;br /&gt;
*Aus der Standard-Peripheral-Library kopieren man ebenfalls von &#039;&#039;&#039;&#039;&#039;Libraries\CMSIS\Device\ST\STM32F4xx\Source\Templates&#039;&#039;&#039;&#039;&#039; die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; in den &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner des Projekts&lt;br /&gt;
&lt;br /&gt;
Anschließend müssen die neuen Dateien in der IDE dem Projekt hinzugefügt werden. Dazu benutzt man &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Rechts Klick -&amp;gt; Add files&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
*Aus dem &#039;&#039;&#039;&#039;&#039;CMSIS&#039;&#039;&#039;&#039;&#039; Ordner im Projekt Verzeichnis werden aus den Unterorder &#039;&#039;&#039;&#039;&#039;Include&#039;&#039;&#039;&#039;&#039; folgende Dateien dem Projekt hinzugefügt:&lt;br /&gt;
**arm_common_tables.h&lt;br /&gt;
**arm_const_structs.h&lt;br /&gt;
**arm_math.h&lt;br /&gt;
**core_cm4.h&lt;br /&gt;
**core_cm4_simd.h&lt;br /&gt;
**core_cmFunc.h&lt;br /&gt;
**core_cmInstr.h&lt;br /&gt;
*Alle Dateien aus den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projektes&lt;br /&gt;
*Die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; aus dem &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner&lt;br /&gt;
&lt;br /&gt;
So sollte die Struktur dann aussehen:&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_7.png|Anwenungs-Grundgerüst]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Da einige Dateien der Libraries später bearbeitet werden müssen und Schreibgeschützt sind, weise ich hier schonmal darauf hin, das der Schreibschutz in der IDE über &#039;&#039;&#039;&#039;&#039;Rechts Klick auf die Datei -&amp;gt; Properties -&amp;gt; Häkchen bei &amp;quot;File is read only&amp;quot; entfernen&#039;&#039;&#039;&#039;&#039; entfert werden kann.&lt;br /&gt;
&lt;br /&gt;
Damit die IDE die Header-Dateien der CMSIS Library auch finden kann, weil diese ja nicht im standard Include Ordner &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; liegen, muss unter &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Build Options -&amp;gt; Search Directories&#039;&#039;&#039;&#039;&#039; der Pfad &#039;&#039;&#039;&#039;&#039;CMSIS\Include&#039;&#039;&#039;&#039;&#039; hinzugefügt werden.&lt;br /&gt;
&lt;br /&gt;
Compiliert man jetzt das Projekt mit &#039;&#039;&#039;&#039;&#039;F7&#039;&#039;&#039;&#039;&#039; gibt es ein paar Fehler Meldungen, weil keine Controller-Reihe ausgewählt wurde. Ebenfalls unter &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Build Options -&amp;gt; Compiler Settings -&amp;gt; #defines&#039;&#039;&#039;&#039;&#039; wird der Define &#039;&#039;&#039;&#039;&#039;STM32F40_41xxx&#039;&#039;&#039;&#039;&#039; hinzugefügt.&lt;br /&gt;
&lt;br /&gt;
Beim erneuten Compilieren sollten sich nun keine neuen Fehler ergeben.&lt;br /&gt;
&lt;br /&gt;
===Das erste Programm===&lt;br /&gt;
Nachdem ein grundsätzliches &amp;quot;Gerüst&amp;quot; fertig ist, kann man den ersten Code schreiben.&lt;br /&gt;
main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC-&amp;gt;AHB1ENR |= RCC_AHB1ENR_GPIODEN;    //Takt für GPIO aktivieren&lt;br /&gt;
    GPIOD-&amp;gt;MODER |= GPIO_MODER_MODER15_0;   //GPIOD Pin15 als Ausgang&lt;br /&gt;
    GPIOD-&amp;gt;BSRRL |= GPIO_BSRR_BS_15;        //GPIOD Pin15 auf High ziehen&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039; wird dann der Debugger gestartet. Hat der Debugger das Projekt erfolgreich übertragen kann die Ausführung mit &#039;&#039;&#039;&#039;&#039;F5&#039;&#039;&#039;&#039;&#039; begonnen werden.&lt;br /&gt;
&lt;br /&gt;
==Libraries einbinden/verwenden==&lt;br /&gt;
===Einbinden der Standard-Peripheral-Library===&lt;br /&gt;
Um nicht immer die einzelnen Register, wie im ersten &amp;quot;bare-metal&amp;quot; Beispiel, aus dem Reference-Manual zu suchen und zu beschreiben, gibt es von ST die Standard Peripheral Library, die diese Aufgaben übernimmt und mit der sich die &amp;quot;normale/grundlegende&amp;quot; (Alles außer USB und Ethernet) Peripherie recht einfach steuern lässt. Um die Library zu verwenden erzeugt man wie oben beschrieben ein neues Grundgerüst und kopiert als erstes den Ordner &#039;&#039;&#039;&#039;&#039;Libraries\STM32F4xx_StdPeriph_Driver&#039;&#039;&#039;&#039;&#039; aus dem Standard-Peripheral-Library Download in das Projekt-Verzeichnis. Außerdem muss man die Datei &#039;&#039;&#039;&#039;&#039;Project\STM32F4xx_StdPeriph_Templates\stm32f4xx_conf.h&#039;&#039;&#039;&#039;&#039; ebenfalls aus dem Standard-Peripheral-Library Download in den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projektes kopieren. In der IDE fügt man den Include-Path &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\inc&#039;&#039;&#039;&#039;&#039; hinzufügen, wie bei der CMSIS-Library (s.o.).&lt;br /&gt;
Außerdem muss noch &#039;&#039;&#039;&#039;&#039;USE_STDPERIPH_DRIVER&#039;&#039;&#039;&#039;&#039; als Define in der IDE hinzugefügt werden (s.o.).&lt;br /&gt;
Danach fügt man die Source- und Include-Dateien aus dem Ordner &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\inc&#039;&#039;&#039;&#039;&#039; und &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\src&#039;&#039;&#039;&#039;&#039; dem Project mit &#039;&#039;&#039;&#039;&#039;&amp;lt;Project Name&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Add files&#039;&#039;&#039;&#039;&#039; hinzu, allerdings nur die, für welche auch der Controller die entsprechende Peripherie besitzt. Beim STM32F4-Discovery Board / STM32F407VG Controller dürfen also nicht folgende Dateien nicht mit hinzugefügt werden, weil diese Peripherie nur bei anderen Controller vorhanden ist:&lt;br /&gt;
&lt;br /&gt;
*stm32f4xx_dma2d.c/.h&lt;br /&gt;
*stm32f4xx_fmc.c/.h&lt;br /&gt;
*stm32f4xx_ltdc.c/.h&lt;br /&gt;
*stm32f4xx_sai.c/.h&lt;br /&gt;
&lt;br /&gt;
Daraus resultiert folgende Struktur:&lt;br /&gt;
&lt;br /&gt;
[[Datei:stdperiphlib_2.png|Header-Struktur]] [[Datei:stdperiphlib_1.png|Source-Struktur]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Anschließen kann die Standard-Peripheral-Library benutz werden.&lt;br /&gt;
main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);&lt;br /&gt;
&lt;br /&gt;
    GPIO_InitTypeDef GPIOD_InitStructure;&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Mode = GPIO_Mode_OUT;     //Als Ausgang&lt;br /&gt;
    GPIOD_InitStructure.GPIO_OType = GPIO_OType_PP;    //Push-Pull Betrieb&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Pin = GPIO_Pin_15;        //Pin 15 (STM32F4-Discovery: Blaue LED)&lt;br /&gt;
    GPIOD_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;  //Kein Pull-Up oder Pull-Down Widerstand aktiviert&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Speed = GPIO_Speed_25MHz; //25MHz Update-Rate&lt;br /&gt;
    GPIO_Init(GPIOD, &amp;amp;GPIOD_InitStructure);&lt;br /&gt;
&lt;br /&gt;
    GPIO_SetBits(GPIOD, GPIO_Pin_15);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Startup-Code, Linker-Script, Takt, FPU usw.==&lt;br /&gt;
===Startup-Code===&lt;br /&gt;
Em::Blocks fügt standardmäßig einen Startup-Code mit in das Projekt ein. Die wichtigsten Dinge die darin erledigt werden sind folgende:&lt;br /&gt;
&lt;br /&gt;
*Stack und Heap wird angelgt&lt;br /&gt;
*Die Vector-Table wird angelegt&lt;br /&gt;
*Ein Default Reset-Handler wird implementiert, dieser erledigt folgende aufgaben:&lt;br /&gt;
**Kopieren der definierten Daten aus dem Flash in den SRAM&lt;br /&gt;
**&#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; wird aufgerfen, wenn &#039;&#039;&#039;&#039;&#039;__NO_SYSTEM_INIT&#039;&#039;&#039;&#039;&#039; nicht definiert ist&lt;br /&gt;
**Sprung in die &#039;&#039;&#039;&#039;&#039;main()&#039;&#039;&#039;&#039;&#039; Funktion&lt;br /&gt;
*Allen anderen Interrupt-Handler wird eine Default-Funktion &#039;&#039;&#039;&#039;&#039;def_irq_handler&#039;&#039;&#039;&#039;&#039; mit einer &#039;&#039;&#039;&#039;&#039;while(1)&#039;&#039;&#039;&#039;&#039;-Schleife zugewiesen, falls kein anderer Interrupt-Handler existiert.&lt;br /&gt;
&lt;br /&gt;
Normalerweise muss am Startup-Code nichts verändert werden.&lt;br /&gt;
&lt;br /&gt;
===Linker-Script===&lt;br /&gt;
Em::Blocks stellt zwei fertige Linker-Scripts bereit, eins für die Ausführung des Programmes aus dem Flash (&#039;&#039;&#039;&#039;&#039;*_flash.ld&#039;&#039;&#039;&#039;&#039;), das andere für die Ausführung aus dem SRAM (&#039;&#039;&#039;&#039;&#039;*_sram.ld&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Normalerweise muss auch hier nichts geändert werden, es sei den Daten sollen in bestimmten Adressbereichen abgelegt werden (z.B. im Core-Coupled RAM), was ich später noch zum Tutorial hinzufüge.&lt;br /&gt;
&lt;br /&gt;
===Der Takt===&lt;br /&gt;
Jeder Controller oder Prozessor braucht einen Takt, indem er die einzelnen Maschinen-Befehle abarbeiten kann.&lt;br /&gt;
Bei den STM32 Mikrocontrollern kann dieser Takt aus verschiedenen Quellen kommen:&lt;br /&gt;
&lt;br /&gt;
1. High Speed Internal Oszillator (HSI)&lt;br /&gt;
&lt;br /&gt;
2. High Speed External Oszillator (HSE)&lt;br /&gt;
&lt;br /&gt;
3. Low Speed Internal Oszillator (LSI)&lt;br /&gt;
&lt;br /&gt;
4. Low Speed External Oszillator (LSE)&lt;br /&gt;
&lt;br /&gt;
5. Phase-Locked Loop (PLL) (generiert den Takt aus den ersten vier Taktquellen durch Teiler und Faktoren)&lt;br /&gt;
&lt;br /&gt;
Nach einem Reset wird der Controller aus der HSI Taktquelle versorgt (16MHz beim STM32F407VG). Um die voll Performance des Controllers zu erreichen muss die PLL verwendet werden, welche den Takt durch geschickte Teiler und Faktoren vervielfältigt, sodass am Ende der Controller mit der maximalen Taktfrequenz läuft. Die notwendige Initialisierung der PLL findet in der Funktion &#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; statt. Die PLL erzeugt zunächst einen Basistakt:&lt;br /&gt;
&lt;br /&gt;
PLL_VCO = (F_HSE / PLL_M) * PLL_N&lt;br /&gt;
&lt;br /&gt;
Aus diesem Takt wird dann der Takt für den Controller-Kern abgeleitet:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = PLL_VCO / PLL_P&lt;br /&gt;
&lt;br /&gt;
Und der Takt für SDIO / USB / RNG (48MHz):&lt;br /&gt;
&lt;br /&gt;
48MHz = PLL_VCO / PLL_Q&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Durch weiter Teiler werden, die Takte für die einzelnen Busse erzeugt, da diese nicht alle beliebig schnell betrieben werden dürfen.&lt;br /&gt;
&lt;br /&gt;
Genaue Angaben findet man zu dem jeweiligen Clock-System des Controllers im Reference Manual.&lt;br /&gt;
&lt;br /&gt;
Ein Blick in den &amp;quot;Kommentar-Header&amp;quot; verrät, dass von einem externen (HSE) Oszillator von 25MHz ausgegangen wird, der die PLL versorgen soll.&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((25MHz / PLL_M(25)) * PLL_N(336)) / PLL_P(2) = 168MHz&lt;br /&gt;
&lt;br /&gt;
Allerdings stimmt diese Rechnung natürlich nur, wenn wirklich ein 25MHz Quarz am Controller angeschlossen ist. Auf dem STM32F4-Discovery Board befindet sich aber nur ein 8MHz Quarz. Demnach gilt:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((8MHz / PLL_M(25)) * PLL_N(336)) / PLL_P(2) = 53.76MHz&lt;br /&gt;
&lt;br /&gt;
Der Controller läuft also nur mit 53.76MHz, wenn wie ober beschrieben ein Projekt erstellt wird. Allerdings kann dieses Problem durch ändern von den betroffen Defines behoben werden:&lt;br /&gt;
 &lt;br /&gt;
*Dazu geht man in die &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; Datei und passt zur Vollständigkeit erstmal die zum Controller passende Tabelle im &amp;quot;Kommentar-Header&amp;quot; an (Z.57f):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      HSE Frequency(Hz)                      | 8000000&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      PLL_M                                  | 8&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Danach passt man den PPL_M Define (Z.254) an:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/************************* PLL Parameters *************************************/&lt;br /&gt;
/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */&lt;br /&gt;
#define PLL_M      8&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Außerdem muss man den HSE_VALUE Define in der &#039;&#039;&#039;&#039;&#039;inc/stm32f4xx.h&#039;&#039;&#039;&#039;&#039; angepasst werden (Z.122):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#if !defined  (HSE_VALUE)&lt;br /&gt;
  #define HSE_VALUE    ((uint32_t)8000000) /*!&amp;lt; Value of the External oscillator in Hz */&lt;br /&gt;
&lt;br /&gt;
#endif /* HSE_VALUE */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine neue Berechnung zeigt:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((8MHz / PLL_M(8)) * PLL_N(336)) / PLL_P(2) = 168MHz&lt;br /&gt;
&lt;br /&gt;
Jetzt läuft der Controller mit maximaler Geschwindigkeit.&lt;br /&gt;
&lt;br /&gt;
Die Theorie wird durch folgendes Programm verifiziert. Der geviertelte System-Takt SYSCLK wir am Pin PC9 ausgegeben. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);&lt;br /&gt;
&lt;br /&gt;
    GPIO_InitTypeDef GPIOC_InitStructure;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Mode = GPIO_Mode_AF;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_OType = GPIO_OType_PP;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Pin = GPIO_Pin_9;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;&lt;br /&gt;
    GPIO_Init(GPIOC, &amp;amp;GPIOC_InitStructure);&lt;br /&gt;
&lt;br /&gt;
    RCC_MCO2Config(RCC_MCO2Source_SYSCLK, RCC_MCO2Div_4);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Die FPU===&lt;br /&gt;
====Allgemeines====&lt;br /&gt;
Damit die FPU richtig verwendet wird, müssen normalerweise zwei Bedingungen erfüllt sein:&lt;br /&gt;
&lt;br /&gt;
1. Der Controller muss in der Initialisierung-Funktion &#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; in &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; die FPU Hardware-seitig aktivieren&lt;br /&gt;
&lt;br /&gt;
2. Damit die FPU auch was zu tuen bekommt, müssen vom Compiler FPU-Instructions erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
Die Em::Blocks IDE verwendet standardmäßig die FPU, wenn eine Vorhanden ist. Hier wird die FPU Hardware-seitig aktiviert (&#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; Z.341):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* FPU settings ------------------------------------------------------------*/&lt;br /&gt;
  #if (__FPU_PRESENT == 1) &amp;amp;&amp;amp; (__FPU_USED == 1)&lt;br /&gt;
    SCB-&amp;gt;CPACR |= ((3UL &amp;lt;&amp;lt; 10*2)|(3UL &amp;lt;&amp;lt; 11*2));  /* set CP10 and CP11 Full Access */&lt;br /&gt;
  #endif&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
__FPU_PRESENT wird in der &#039;&#039;&#039;&#039;&#039;stm32f4xx.h&#039;&#039;&#039;&#039;&#039; definiert.&lt;br /&gt;
__FPU_USED wird von der IDE übernommen (siehe Build-Log): &#039;&#039;&#039;&#039;&#039;-D__FPU_USED&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Außerdem wird der Compiler von der IDE standardmäßig mit dem Argument &#039;&#039;&#039;&#039;&#039;-mfloat-abi=hard&#039;&#039;&#039;&#039;&#039; aufgerufen, wodurch FPU-Instructions erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
====FPU abschalten====&lt;br /&gt;
Um die FPU ab zu schalten (Mir würde jetzt nur Strom sparen als Grund einfallen) geht man wie folgt vor:&lt;br /&gt;
&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick Build options -&amp;gt; Device -&amp;gt; Policy&#039;&#039;&#039;&#039;&#039; wählt man &#039;&#039;&#039;&#039;&#039;Use target settings&#039;&#039;&#039;&#039;&#039; und über nimmt die Einstellungen, die vorher dort eingetragen waren, allerdings lässt man das Feld &#039;&#039;&#039;&#039;&#039;FP-hardware&#039;&#039;&#039;&#039;&#039; frei.&lt;br /&gt;
&lt;br /&gt;
[[Datei:fpu_1.png|FPU Abschalten Schritt 1]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;Compiler Settings -&amp;gt; Policy&#039;&#039;&#039;&#039;&#039; wählt man dann &#039;&#039;&#039;&#039;&#039;Use target options only&#039;&#039;&#039;&#039;&#039;. Dann kann man unter &#039;&#039;&#039;&#039;&#039;Categories&#039;&#039;&#039;&#039;&#039; die Option &#039;&#039;&#039;&#039;&#039;ARM FPU architecture&#039;&#039;&#039;&#039;&#039; auswählen. Dort stehen dann drei Möglichkeiten für die FPU zur Verfügung:&lt;br /&gt;
&lt;br /&gt;
1. Software-FPU-Library für Gleitkomma-Berechnung verwenden - Keine FPU-Instructions werden generiert (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=soft&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
2. Eine Mischung aus Software- und Hardware-FPU wird verwendet (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=softfp&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
3. Hardware-FPU wird für Gleitkomma-Berechnungen verwendet (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=hard&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
[[Datei:fpu_2.png|FPU Abschalten Schritt 2]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Um die FPU ab zu schalten wählt man natürlich die erste Möglichkeit.&lt;br /&gt;
Bei der 2. und 3. Möglichkeit fügt die IDE auch den Define &#039;&#039;&#039;&#039;&#039;__FPU_USED&#039;&#039;&#039;&#039;&#039; hinzu. Bei Der ersten Möglichkeit nicht. Der Code muss also nicht verändert / auskommentiert werden.&lt;br /&gt;
&lt;br /&gt;
Um die FPU wieder zu aktivieren müssen alle Schritte wieder rückgängig gemacht werden.&lt;br /&gt;
&lt;br /&gt;
Am besten ist es einfach mal alle Möglichkeiten im Einzelschritt durch zu probieren. Dann stellt man schnell fest, ob die FPU aktiviert wir oder nicht. Ein Blick in den erweiterten &#039;&#039;&#039;&#039;&#039;Build-Log&#039;&#039;&#039;&#039;&#039; gibt auch schnell Aufschluss darüber, wie der Compiler aufgerufen wird (siehe Kapitel [http://www.mikrocontroller.net/articles/STM32_-_Einstieg_mit_Em::Blocks#Compilieren Compilieren]).&lt;br /&gt;
&lt;br /&gt;
====Test Programm für die FPU====&lt;br /&gt;
Hier ein kleines Testprogramm, dass misst wie viele Taktzyklen für eine Gleitkomma-Multiplikation gebraucht werden. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define CORE_SysTickEn()    (*((u32*)0xE0001000)) = 0x40000001&lt;br /&gt;
#define CORE_SysTickDis()   (*((u32*)0xE0001000)) = 0x40000000&lt;br /&gt;
#define CORE_GetSysTick()   (*((u32*)0xE0001004))&lt;br /&gt;
&lt;br /&gt;
uint32_t t1, t2, dt;&lt;br /&gt;
float x, y, z;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    x = 53.64f;&lt;br /&gt;
    y = 0.27f;&lt;br /&gt;
&lt;br /&gt;
    CORE_SysTickEn();&lt;br /&gt;
    t1 = CORE_GetSysTick();&lt;br /&gt;
&lt;br /&gt;
    z = x * y;&lt;br /&gt;
&lt;br /&gt;
    t2 = CORE_GetSysTick();&lt;br /&gt;
    CORE_SysTickDis();&lt;br /&gt;
&lt;br /&gt;
    dt = t2 - t1;&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mein Ergebnis:&lt;br /&gt;
*Mit Hardware-FPU:  dt = 25&lt;br /&gt;
*Ohne Hardware-FPU: dt = 83&lt;br /&gt;
&lt;br /&gt;
Die Messung alleine braucht davon 9 Takt-Zyklen. Zum Vergleich ist das aber nicht relevant.&lt;br /&gt;
&lt;br /&gt;
==Booten aus dem SRAM==&lt;br /&gt;
STM32 Controller haben die Möglichkeit Code aus dem Flash als auch aus dem SRAM auszuführen. Um eine Anwenung per Debugger in des SRAM zu laden sind nur wenige Schritte erforderlich:&lt;br /&gt;
&lt;br /&gt;
*Um das Linkerscript für den SRAM zu verwenden geht man zu: &#039;&#039;&#039;&#039;&#039;Build options... -&amp;gt; Device&#039;&#039;&#039;&#039;&#039; dort wählt man unter &#039;&#039;&#039;&#039;&#039;Policy&#039;&#039;&#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;Use target settings&#039;&#039;&#039;&#039;&#039; aus und übernimmt die vorherigen Einstellungen, nur unter &#039;&#039;&#039;&#039;&#039;Linker script*&#039;&#039;&#039;&#039;&#039; gibt man &#039;&#039;&#039;&#039;&#039;.\stm32f407vg_sram.ld&#039;&#039;&#039;&#039;&#039; an&lt;br /&gt;
&lt;br /&gt;
*Dann muss man noch unter &#039;&#039;&#039;&#039;&#039;Debug -&amp;gt; Interfaces -&amp;gt; Settings&#039;&#039;&#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;Vector table start&#039;&#039;&#039;&#039;&#039; auf 0x20000000 ändern und &#039;&#039;&#039;&#039;&#039;Execute from RAM&#039;&#039;&#039;&#039;&#039; auswählen.&lt;br /&gt;
&lt;br /&gt;
Anschließend kann man die Anwendung ganz normal debuggen. Nach einem Reset muss die Anwenung erneut mit dem Debugger gestartet werden.&lt;br /&gt;
&lt;br /&gt;
=Fortsetzung folgt..=&lt;br /&gt;
Kritik, Wünsche usw. sind gerne erwünscht, am besten hier in den Thread posten: [http://www.mikrocontroller.net/topic/323750 Neues STM32 Tutorial]&lt;br /&gt;
&lt;br /&gt;
[[Category:ARM]]&lt;br /&gt;
[[Category:STM32]]&lt;/div&gt;</summary>
		<author><name>Avrprogger</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=STM32_-_Einstieg_mit_Em::Blocks&amp;diff=81514</id>
		<title>STM32 - Einstieg mit Em::Blocks</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=STM32_-_Einstieg_mit_Em::Blocks&amp;diff=81514"/>
		<updated>2014-02-10T16:39:48Z</updated>

		<summary type="html">&lt;p&gt;Avrprogger: vbnb&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In diesem Tutorial werde ich versuchen, möglichst einfach, die ersten Schritte zur Entwicklung von STM32 Anwenungen mit der Em::Blocks IDE zu erklären. Hier soll nicht so stark auf die einzelnen Peripherie-Module der Controller eingegangen werden, sondern mehr auf die IDE und die verschieden Libraries, wie die CMSIS Library, die DSP-Library, die Standard-Peripheral-Library, die USB-Library und vllt. über Ethernet. Ich denke ein Kapitel zu FreeRTOS wird es auch geben. Auserdem steht im Vordergrund Sachen wie z.B. booten aus dem SRAM, In-Application-Programming, FPU, Core-Coupled-RAM usw. Mal sehn wie weit ich komme ;)&lt;br /&gt;
&lt;br /&gt;
==Die Entwicklungsumgebung==&lt;br /&gt;
===Hardware===&lt;br /&gt;
Zum testen der Anwendungen, benutze ich das STM32F4-Discovery Board, welches einen Debugger, Peripherie und natürlich einen STM32 Controller (STM32F407VGT6) enthält. Deshalb sind alle Beispiele hier für den STM32F407VG Controller ausgelegt, können aber meisten 1:1 auf andere Controller portiert werden. Ich werde auch möglichsts keine STM32F4-Discovery Board spezifischen Libraries verwenden, damit der Portierungs-Vorgang möglichsts einfach bleibt.&lt;br /&gt;
&lt;br /&gt;
===Software===&lt;br /&gt;
In diesem Tutorial verwende ich [http://www.emblocks.org/ Em::Blocks] als IDE. Em::Blocks ist eine kostenlose, uneingeschränkte IDE, die alle STM32 Mikrcontroller unterstützt und sehr einfach zu bedienen ist.&lt;br /&gt;
nach dem Download kann die IDE per Dialog, sehr einfach, installiert werden. Als Compiler beinhaltet Em::Blocks den &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
Die IDE unterstützt zurzeit den ST-Link, den J-Link und es gibt eine Generic-Vorlage, durch welche andere Debugger konfiguriert werden können.&lt;br /&gt;
&lt;br /&gt;
Außerdem muss noch der passende Treiber für den Debugger installiert werden. Verwendet man ein Discovery-Board muss der [http://www.st.com/web/catalog/tools/FM146/CL1984/SC724/SS1677/PF251168 ST-Link/V2]-Treiber heruntergeladen und installiert werden. (Die Installation muss evtl. als Administrator ausgeführt werden, da sonst die Installation unvollständig wird.) Nach der Installation des Treibers kann man den Debugger über die entsprechende USB Schnittstelle an den PC anschließen und es sollte die Meldung von Windows kommen, dass der richtige Treiber gefunden wurde.&lt;br /&gt;
&lt;br /&gt;
===Libraries===&lt;br /&gt;
Zum programmieren benötigt man noch die [http://www.arm.com/products/processors/cortex-m/cortex-microcontroller-software-interface-standard.php CMSIS] und die Standard-Peripheral-Library (z.B. für die F4 Controller [http://www.st.com/stonline/stappl/productcatalog/app?page=partNumberSearchPage&amp;amp;levelid=SS1577&amp;amp;parentid=1743&amp;amp;resourcetype=SW Standard-Peripheral-Library-F4]), die man am besten in einen Ordner (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\STM32&#039;&#039;&#039;&#039;&#039;) entpackt&lt;br /&gt;
&lt;br /&gt;
==Basis-Wissen zur IDE==&lt;br /&gt;
Einige Grundfunktionalitäten der IDE:&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von Dateien zum Projekt===&lt;br /&gt;
Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf &amp;lt;ProjektName&amp;gt; -&amp;gt; Add files...&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Enfernen von Dateien aus dem Projekt===&lt;br /&gt;
Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf die Datei / mehrere Dateien auswählen -&amp;gt; Remove file from project&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
Die Dateien werden lediglich aus dem Projekt entfernt und nicht von der Festplatte gelöscht.&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von Include-Pfaden===&lt;br /&gt;
Sofern die Include-Datei(en) nicht im standard Include-Ordner &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; des Projektes liegen, muss man den Pfad zum Projekt hinzufügen, damit der Compiler die Include-Dateien später auch finden kann. Man geht wie folgt vor: Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf &amp;lt;ProjektName&amp;gt; -&amp;gt; Build options... -&amp;gt; Search Directories -&amp;gt; Add&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Compilieren===&lt;br /&gt;
Entweder über das &#039;&#039;&#039;&#039;&#039;Build&#039;&#039;&#039;&#039;&#039; Menü oder über &#039;&#039;&#039;&#039;&#039;F7&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Um eine genau Ausgabe des Compiler-Aufrufes mit allen Argumenten zu bekommen, geht man im &#039;&#039;&#039;&#039;&#039;Settings&#039;&#039;&#039;&#039;&#039; Menü auf &#039;&#039;&#039;&#039;&#039;Tools...&#039;&#039;&#039;&#039;&#039; und dann auf &#039;&#039;&#039;&#039;&#039;Toolchain executables&#039;&#039;&#039;&#039;&#039;. Ganz unten, unter &#039;&#039;&#039;&#039;&#039;Logging&#039;&#039;&#039;&#039;&#039; kann man dann &#039;&#039;&#039;&#039;&#039;Full command line&#039;&#039;&#039;&#039;&#039; auswählen.&lt;br /&gt;
&lt;br /&gt;
===Debuggen===&lt;br /&gt;
*Als erstes den Debugger starten über das &#039;&#039;&#039;&#039;&#039;Debug&#039;&#039;&#039;&#039;&#039; Menü und &#039;&#039;&#039;&#039;&#039;Start/stop Debug Session&#039;&#039;&#039;&#039;&#039; oder über &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
*Danach läuft die Anwendung auf dem Controller und warten im &#039;&#039;&#039;&#039;&#039;Reset_Handler&#039;&#039;&#039;&#039;&#039; auf Einzelschritt- bzw. Run- Befehle (&#039;&#039;&#039;&#039;&#039;F5, F10, F11&#039;&#039;&#039;&#039;&#039; usw..(siehe &#039;&#039;&#039;&#039;&#039;Debug-Menü&#039;&#039;&#039;&#039;&#039; für alle Möglichkeiten))&lt;br /&gt;
&lt;br /&gt;
*Mit &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039; wird die Debug-Session auch wieder beendet&lt;br /&gt;
&lt;br /&gt;
*Unter &#039;&#039;&#039;&#039;&#039;Debug -&amp;gt; Interfaces -&amp;gt; Target settings&#039;&#039;&#039;&#039;&#039; können Eigenschaften, wie z.B &#039;&#039;&#039;&#039;&#039;Run to main()&#039;&#039;&#039;&#039;&#039; aktiviert werden.&lt;br /&gt;
&lt;br /&gt;
===Projekt als Template abspeichern===&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;File -&amp;gt; Save project as template...&#039;&#039;&#039;&#039;&#039;. Das Template erscheint dann im Projekt-Dialog unter &#039;&#039;&#039;&#039;&#039;User templates&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Das erste Projekt erstellen==&lt;br /&gt;
Hier erkläre ich, wie man am Besten (aus meiner Sicht), ein neues Projekt von Grund auf erstellt, sodass man hinterher, den Controller-Kern über die CMSIS-Library und die Peripherie über die Register steuern kann.&lt;br /&gt;
&lt;br /&gt;
===1. Projekt mit der IDE erstellen===&lt;br /&gt;
Nach der Installation der oben beschriebenen Komponenten erstellt man am besten ein Verzeichnis (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\EmBlocks&#039;&#039;&#039;&#039;&#039;), indem später alle Projekte gespeichert werden. Für Libraries kann man auch noch ein Verzeichnis (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\STM32&#039;&#039;&#039;&#039;&#039;) erstellen, wo alle Libraries gespeichert werden, die man für die Projekt brauchen.&lt;br /&gt;
&lt;br /&gt;
Als nächstes starten man EmBlocks. Bei dem ersten Start öffnet sich ein Fenster, wo verschiedene Compiler angezeigt werden, die Em::Blocks findet. Dort wählt man den &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039; aus und klickt &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039;. Nun sollte sich das Hauptfenster von Em::Blocks öffnen. Über &#039;&#039;&#039;&#039;&#039;Create a new Project&#039;&#039;&#039;&#039;&#039; oder &#039;&#039;&#039;&#039;&#039;File -&amp;gt; New -&amp;gt; Project&#039;&#039;&#039;&#039;&#039; ruft man den Projekt-Dialog auf und kann ein neues Projekt erzeugen.&lt;br /&gt;
&lt;br /&gt;
Auf der Ersten Seite wählen man den &#039;&#039;&#039;&#039;&#039;STmicro-ARM&#039;&#039;&#039;&#039;&#039; Projekt-Typ aus.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_1.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auf der nächsten Seite wird man darauf hingewiesen, dass das der entsprechende Projekt-Typ-Dialog ausgeführt wird. Hier kann man ein Häkchen bei &#039;&#039;&#039;&#039;&#039;Skip this page next time&#039;&#039;&#039;&#039;&#039; setzen und auf &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; klicken.&lt;br /&gt;
&lt;br /&gt;
Im nächsten Schritt wählen man das zuvor erstellt Verzeichnis unter &#039;&#039;&#039;&#039;&#039;Folder to create Project in&#039;&#039;&#039;&#039;&#039; aus, indem später alle Projekt gespeichert werden. Außerdem geben wir dem Projekt einen Namen (z.B. &#039;&#039;&#039;&#039;&#039;FirstProject&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_2.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danach muss man einen Compiler auswählen und bestimmen, welche Projekt-Konfigurationen erszeugt werden sollen. Unter &#039;&#039;&#039;&#039;&#039;Compiler&#039;&#039;&#039;&#039;&#039; wählt man &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039; und man kann das Häkchen bei &#039;&#039;&#039;&#039;&#039;Create &amp;quot;Release&amp;quot; configuration&#039;&#039;&#039;&#039;&#039; entfernen, da diese unnötig ist, die Debug-Konfiguration sollte eig. immer ausreichen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_3.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auf den folgenden Seite wird der Controller ausgewählt. Verwendet man ein STM32F4-Discovery Board müssen folgende Dinge gewählt werden: &#039;&#039;&#039;&#039;&#039;Cortex_M4 (F3xx - F4xx) -&amp;gt; STM32F4xx (Cortex M4 with FPU) -&amp;gt; STM32F407VG&#039;&#039;&#039;&#039;&#039;. Leider sind die Auswahl Möglichkeiten nicht ganz richtig, da auch die F3 Controller einen Cortex M4 Kern und eine FPU haben (Ist aber nicht so wichtig, ist nur eine formale Sache). Außerdem entfernt man das Häkchen bei &#039;&#039;&#039;&#039;&#039;Standard Peripherals Library&#039;&#039;&#039;&#039;&#039; (Wie man die Standard-Peripheral-Library einbindet und verwendet erkläre ich später). Man kann auch das Häkchen bei &#039;&#039;&#039;&#039;&#039;Create hex file for Realease target&#039;&#039;&#039;&#039;&#039; entfernen.&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;Stack Size&#039;&#039;&#039;&#039;&#039; und &#039;&#039;&#039;&#039;&#039;Heap Size&#039;&#039;&#039;&#039;&#039; wird die Größe von Stack und Heap festgelegt. Für eine erste Anwendung kann man die Einstellungen so lassen (Stack-Size: 0x0100 =&amp;gt; 256 Byte Stack und Heap-Size: 0x0000 =&amp;gt; kein Heap). Mit &#039;&#039;&#039;&#039;&#039;Finish&#039;&#039;&#039;&#039;&#039; ist der Projekt Dialog abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_4.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danach sollten sich zwei neue Fenster öffnen, um die Debug-Eigenschaften fest zu legen.&lt;br /&gt;
Verwendet man ein Discovery Board/ST-Link müssen die Einstellungen wie auf dem Bild gewählt werden. Über den Button &#039;&#039;&#039;&#039;&#039;Settings&#039;&#039;&#039;&#039;&#039; öffnet sich das zweite Fenster, falls sich dieses nicht schon von alleine öffnen sollte. Nach den Schließen der Fenster über &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; ist der Projekt Dialog beendet und ein neues Projekt steht zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_5_1.png|Debug Eigenschaften 1. Fenster]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_5_2.png|Debug Eigenschaften 2. Fenster]]&lt;br /&gt;
&lt;br /&gt;
===2. CMSIS-Library und Startup-Code hinzufügen===&lt;br /&gt;
Wenn man sich, nachdem man ein neues Projekt in der IDE erstellt hat, die bereits vorhandenen Dateien im Projekt ansieht, stellt man fest, das bereits ein Ordner &#039;&#039;&#039;&#039;&#039;cmsis&#039;&#039;&#039;&#039;&#039; existiert, der einige wichtige Include-Dateien der CMSIS-Library enthält. Allerdings sind das wirklich nur die wichtigsten Include-Dateien der CMSIS-Library und dazu noch, die aus einer älternen Version. Ich ziehe es deshalb vor die &amp;quot;Mini-CMSIS-Libraray&amp;quot; und die &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c/.h&#039;&#039;&#039;&#039;&#039; Dateien des Projektes durch aktuellere Versionen zu ersetzen. So ist später auch die Integration  von anderen Libraries, wie z.B. der CMSIS-DSP-Libarary einfacher.  &lt;br /&gt;
&lt;br /&gt;
Zunächst gehen man in das Projekt-Verzeichnis und löscht:&lt;br /&gt;
*Den Ordner &#039;&#039;&#039;&#039;&#039;cmsis&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Alle Dateien im Include Verzeichnis &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; im &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner&lt;br /&gt;
&lt;br /&gt;
Außerdem entfernt man auch alle gelöschten Dateien in der IDE aus dem Projekt mit &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Rechts Klick -&amp;gt; Remove file from project&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Es sollte folgende Verzeichnis Struktur überbleiben:&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_6.png|Überbleibende Dateien]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Jetzt müssen die gelöschten Dateien durch die aktuelleren ersetzt werden.&lt;br /&gt;
&lt;br /&gt;
*Dazu kopieren man den gesamten Ordner &#039;&#039;&#039;&#039;&#039;CMSIS&#039;&#039;&#039;&#039;&#039; aus dem CMSIS Download in das Projekt Verzeichnis.&lt;br /&gt;
&lt;br /&gt;
*Aus dem Standard-Peripheral-Library Download kopiert man von &#039;&#039;&#039;&#039;&#039;Libraries\CMSIS\Device\ST\STM32F4xx\Include&#039;&#039;&#039;&#039;&#039; alle Dateien in den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projekt Verzeichnisses&lt;br /&gt;
&lt;br /&gt;
*Aus der Standard-Peripheral-Library kopieren man ebenfalls von &#039;&#039;&#039;&#039;&#039;Libraries\CMSIS\Device\ST\STM32F4xx\Source\Templates&#039;&#039;&#039;&#039;&#039; die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; in den &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner des Projekts&lt;br /&gt;
&lt;br /&gt;
Anschließend müssen die neuen Dateien in der IDE dem Projekt hinzugefügt werden. Dazu benutzt man &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Rechts Klick -&amp;gt; Add files&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
*Aus dem &#039;&#039;&#039;&#039;&#039;CMSIS&#039;&#039;&#039;&#039;&#039; Ordner im Projekt Verzeichnis werden aus den Unterorder &#039;&#039;&#039;&#039;&#039;Include&#039;&#039;&#039;&#039;&#039; folgende Dateien dem Projekt hinzugefügt:&lt;br /&gt;
**arm_common_tables.h&lt;br /&gt;
**arm_const_structs.h&lt;br /&gt;
**arm_math.h&lt;br /&gt;
**core_cm4.h&lt;br /&gt;
**core_cm4_simd.h&lt;br /&gt;
**core_cmFunc.h&lt;br /&gt;
**core_cmInstr.h&lt;br /&gt;
*Alle Dateien aus den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projektes&lt;br /&gt;
*Die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; aus dem &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner&lt;br /&gt;
&lt;br /&gt;
So sollte die Struktur dann aussehen:&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_7.png|Anwenungs-Grundgerüst]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Da einige Dateien der Libraries später bearbeitet werden müssen und Schreibgeschützt sind, weise ich hier schonmal darauf hin, das der Schreibschutz in der IDE über &#039;&#039;&#039;&#039;&#039;Rechts Klick auf die Datei -&amp;gt; Properties -&amp;gt; Häkchen bei &amp;quot;File is read only&amp;quot; entfernen&#039;&#039;&#039;&#039;&#039; entfert werden kann.&lt;br /&gt;
&lt;br /&gt;
Damit die IDE die Header-Dateien der CMSIS Library auch finden kann, weil diese ja nicht im standard Include Ordner &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; liegen, muss unter &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Build Options -&amp;gt; Search Directories&#039;&#039;&#039;&#039;&#039; der Pfad &#039;&#039;&#039;&#039;&#039;CMSIS\Include&#039;&#039;&#039;&#039;&#039; hinzugefügt werden.&lt;br /&gt;
&lt;br /&gt;
Compiliert man jetzt das Projekt mit &#039;&#039;&#039;&#039;&#039;F7&#039;&#039;&#039;&#039;&#039; gibt es ein paar Fehler Meldungen, weil keine Controller-Reihe ausgewählt wurde. Ebenfalls unter &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Build Options -&amp;gt; Compiler Settings -&amp;gt; #defines&#039;&#039;&#039;&#039;&#039; wird der Define &#039;&#039;&#039;&#039;&#039;STM32F40_41xxx&#039;&#039;&#039;&#039;&#039; hinzugefügt.&lt;br /&gt;
&lt;br /&gt;
Beim erneuten Compilieren sollten sich nun keine neuen Fehler ergeben.&lt;br /&gt;
&lt;br /&gt;
===Das erste Programm===&lt;br /&gt;
Nachdem ein grundsätzliches &amp;quot;Gerüst&amp;quot; fertig ist, kann man den ersten Code schreiben.&lt;br /&gt;
main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC-&amp;gt;AHB1ENR |= RCC_AHB1ENR_GPIODEN;    //Takt für GPIO aktivieren&lt;br /&gt;
    GPIOD-&amp;gt;MODER |= GPIO_MODER_MODER15_0;   //GPIOD Pin15 als Ausgang&lt;br /&gt;
    GPIOD-&amp;gt;BSRRL |= GPIO_BSRR_BS_15;        //GPIOD Pin15 auf High ziehen&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039; wird dann der Debugger gestartet. Hat der Debugger das Projekt erfolgreich übertragen kann die Ausführung mit &#039;&#039;&#039;&#039;&#039;F5&#039;&#039;&#039;&#039;&#039; begonnen werden.&lt;br /&gt;
&lt;br /&gt;
==Libraries einbinden/verwenden==&lt;br /&gt;
===Einbinden der Standard-Peripheral-Library===&lt;br /&gt;
Um nicht immer die einzelnen Register, wie im ersten &amp;quot;bare-metal&amp;quot; Beispiel, aus dem Reference-Manual zu suchen und zu beschreiben, gibt es von ST die Standard Peripheral Library, die diese Aufgaben übernimmt und mit der sich die &amp;quot;normale/grundlegende&amp;quot; (Alles außer USB und Ethernet) Peripherie recht einfach steuern lässt. Um die Library zu verwenden erzeugt man wie oben beschrieben ein neues Grundgerüst und kopiert als erstes den Ordner &#039;&#039;&#039;&#039;&#039;Libraries\STM32F4xx_StdPeriph_Driver&#039;&#039;&#039;&#039;&#039; aus dem Standard-Peripheral-Library Download in das Projekt-Verzeichnis. Außerdem muss man die Datei &#039;&#039;&#039;&#039;&#039;Project\STM32F4xx_StdPeriph_Templates\stm32f4xx_conf.h&#039;&#039;&#039;&#039;&#039; ebenfalls aus dem Standard-Peripheral-Library Download in den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projektes kopieren. In der IDE fügt man den Include-Path &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\inc&#039;&#039;&#039;&#039;&#039; hinzufügen, wie bei der CMSIS-Library (s.o.).&lt;br /&gt;
Außerdem muss noch &#039;&#039;&#039;&#039;&#039;USE_STDPERIPH_DRIVER&#039;&#039;&#039;&#039;&#039; als Define in der IDE hinzugefügt werden (s.o.).&lt;br /&gt;
Danach fügt man die Source- und Include-Dateien aus dem Ordner &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\inc&#039;&#039;&#039;&#039;&#039; und &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\src&#039;&#039;&#039;&#039;&#039; dem Project mit &#039;&#039;&#039;&#039;&#039;&amp;lt;Project Name&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Add files&#039;&#039;&#039;&#039;&#039; hinzu, allerdings nur die, für welche auch der Controller die entsprechende Peripherie besitzt. Beim STM32F4-Discovery Board / STM32F407VG Controller dürfen also nicht folgende Dateien nicht mit hinzugefügt werden, weil diese Peripherie nur bei anderen Controller vorhanden ist:&lt;br /&gt;
&lt;br /&gt;
*stm32f4xx_dma2d.c/.h&lt;br /&gt;
*stm32f4xx_fmc.c/.h&lt;br /&gt;
*stm32f4xx_ltdc.c/.h&lt;br /&gt;
*stm32f4xx_sai.c/.h&lt;br /&gt;
&lt;br /&gt;
Daraus resultiert folgende Struktur:&lt;br /&gt;
&lt;br /&gt;
[[Datei:stdperiphlib_2.png|Header-Struktur]] [[Datei:stdperiphlib_1.png|Source-Struktur]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Anschließen kann die Standard-Peripheral-Library benutz werden.&lt;br /&gt;
main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);&lt;br /&gt;
&lt;br /&gt;
    GPIO_InitTypeDef GPIOD_InitStructure;&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Mode = GPIO_Mode_OUT;     //Als Ausgang&lt;br /&gt;
    GPIOD_InitStructure.GPIO_OType = GPIO_OType_PP;    //Push-Pull Betrieb&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Pin = GPIO_Pin_15;        //Pin 15 (STM32F4-Discovery: Blaue LED)&lt;br /&gt;
    GPIOD_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;  //Kein Pull-Up oder Pull-Down Widerstand aktiviert&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Speed = GPIO_Speed_25MHz; //25MHz Update-Rate&lt;br /&gt;
    GPIO_Init(GPIOD, &amp;amp;GPIOD_InitStructure);&lt;br /&gt;
&lt;br /&gt;
    GPIO_SetBits(GPIOD, GPIO_Pin_15);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Startup-Code, Linker-Script, Takt, FPU usw.==&lt;br /&gt;
===Startup-Code===&lt;br /&gt;
Em::Blocks fügt standardmäßig einen Startup-Code mit in das Projekt ein. Die wichtigsten Dinge die darin erledigt werden sind folgende:&lt;br /&gt;
&lt;br /&gt;
*Stack und Heap wird angelgt&lt;br /&gt;
*Die Vector-Table wird angelegt&lt;br /&gt;
*Ein Default Reset-Handler wird implementiert, dieser erledigt folgende aufgaben:&lt;br /&gt;
**Kopieren der definierten Daten aus dem Flash in den SRAM&lt;br /&gt;
**&#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; wird aufgerfen, wenn &#039;&#039;&#039;&#039;&#039;__NO_SYSTEM_INIT&#039;&#039;&#039;&#039;&#039; nicht definiert ist&lt;br /&gt;
**Sprung in die &#039;&#039;&#039;&#039;&#039;main()&#039;&#039;&#039;&#039;&#039; Funktion&lt;br /&gt;
*Allen anderen Interrupt-Handler wird eine Default-Funktion &#039;&#039;&#039;&#039;&#039;def_irq_handler&#039;&#039;&#039;&#039;&#039; mit einer &#039;&#039;&#039;&#039;&#039;while(1)&#039;&#039;&#039;&#039;&#039;-Schleife zugewiesen, falls kein anderer Interrupt-Handler existiert.&lt;br /&gt;
&lt;br /&gt;
Normalerweise muss am Startup-Code nichts verändert werden.&lt;br /&gt;
&lt;br /&gt;
===Linker-Script===&lt;br /&gt;
Em::Blocks stellt zwei fertige Linker-Scripts bereit, eins für die Ausführung des Programmes aus dem Flash (&#039;&#039;&#039;&#039;&#039;*_flash.ld&#039;&#039;&#039;&#039;&#039;), das andere für die Ausführung aus dem SRAM (&#039;&#039;&#039;&#039;&#039;*_sram.ld&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Normalerweise muss auch hier nichts geändert werden, es sei den Daten sollen in bestimmten Adressbereichen abgelegt werden (z.B. im Core-Coupled RAM), was ich später noch zum Tutorial hinzufüge.&lt;br /&gt;
&lt;br /&gt;
===Der Takt===&lt;br /&gt;
Jeder Controller oder Prozessor braucht einen Takt, indem er die einzelnen Maschinen-Befehle abarbeiten kann.&lt;br /&gt;
Bei den STM32 Mikrocontrollern kann dieser Takt aus verschiedenen Quellen kommen:&lt;br /&gt;
&lt;br /&gt;
1. High Speed Internal Oszillator (HSI)&lt;br /&gt;
&lt;br /&gt;
2. High Speed External Oszillator (HSE)&lt;br /&gt;
&lt;br /&gt;
3. Low Speed Internal Oszillator (LSI)&lt;br /&gt;
&lt;br /&gt;
4. Low Speed External Oszillator (LSE)&lt;br /&gt;
&lt;br /&gt;
5. Phase-Locked Loop (PLL) (generiert den Takt aus den ersten vier Taktquellen durch Teiler und Faktoren)&lt;br /&gt;
&lt;br /&gt;
Nach einem Reset wird der Controller aus der HSI Taktquelle versorgt (16MHz beim STM32F407VG). Um die voll Performance des Controllers zu erreichen muss die PLL verwendet werden, welche den Takt durch geschickte Teiler und Faktoren vervielfältigt, sodass am Ende der Controller mit der maximalen Taktfrequenz läuft. Die notwendige Initialisierung der PLL findet in der Funktion &#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; statt. Die PLL erzeugt zunächst einen Basistakt:&lt;br /&gt;
&lt;br /&gt;
PLL_VCO = (F_HSE / PLL_M) * PLL_N&lt;br /&gt;
&lt;br /&gt;
Aus diesem Takt wird dann der Takt für den Controller-Kern abgeleitet:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = PLL_VCO / PLL_P&lt;br /&gt;
&lt;br /&gt;
Und der Takt für SDIO / USB / RNG (48MHz):&lt;br /&gt;
&lt;br /&gt;
48MHz = PLL_VCO / PLL_Q&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Durch weiter Teiler werden, die Takte für die einzelnen Busse erzeugt, da diese nicht alle beliebig schnell betrieben werden dürfen.&lt;br /&gt;
&lt;br /&gt;
Genaue Angaben findet man zu dem jeweiligen Clock-System des Controllers im Reference Manual.&lt;br /&gt;
&lt;br /&gt;
Ein Blick in den &amp;quot;Kommentar-Header&amp;quot; verrät, dass von einem externen (HSE) Oszillator von 25MHz ausgegangen wird, der die PLL versorgen soll.&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((25MHz / PLL_M(25)) * PLL_N(336)) / PLL_P(2) = 168MHz&lt;br /&gt;
&lt;br /&gt;
Allerdings stimmt diese Rechnung natürlich nur, wenn wirklich ein 25MHz Quarz am Controller angeschlossen ist. Auf dem STM32F4-Discovery Board befindet sich aber nur ein 8MHz Quarz. Demnach gilt:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((8MHz / PLL_M(25)) * PLL_N(336)) / PLL_P(2) = 53.76MHz&lt;br /&gt;
&lt;br /&gt;
Der Controller läuft also nur mit 53.76MHz, wenn wie ober beschrieben ein Projekt erstellt wird. Allerdings kann dieses Problem durch ändern von den betroffen Defines behoben werden:&lt;br /&gt;
 &lt;br /&gt;
*Dazu geht man in die &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; Datei und passt zur Vollständigkeit erstmal die zum Controller passende Tabelle im &amp;quot;Kommentar-Header&amp;quot; an (Z.57f):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      HSE Frequency(Hz)                      | 8000000&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      PLL_M                                  | 8&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Danach passt man den PPL_M Define (Z.254) an:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/************************* PLL Parameters *************************************/&lt;br /&gt;
/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */&lt;br /&gt;
#define PLL_M      8&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Außerdem muss man den HSE_VALUE Define in der &#039;&#039;&#039;&#039;&#039;inc/stm32f4xx.h&#039;&#039;&#039;&#039;&#039; angepasst werden (Z.122):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#if !defined  (HSE_VALUE)&lt;br /&gt;
  #define HSE_VALUE    ((uint32_t)8000000) /*!&amp;lt; Value of the External oscillator in Hz */&lt;br /&gt;
&lt;br /&gt;
#endif /* HSE_VALUE */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine neue Berechnung zeigt:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((8MHz / PLL_M(8)) * PLL_N(336)) / PLL_P(2) = 168MHz&lt;br /&gt;
&lt;br /&gt;
Jetzt läuft der Controller mit maximaler Geschwindigkeit.&lt;br /&gt;
&lt;br /&gt;
Die Theorie wird durch folgendes Programm verifiziert. Der geviertelte System-Takt SYSCLK wir am Pin PC9 ausgegeben. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);&lt;br /&gt;
&lt;br /&gt;
    GPIO_InitTypeDef GPIOC_InitStructure;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Mode = GPIO_Mode_AF;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_OType = GPIO_OType_PP;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Pin = GPIO_Pin_9;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;&lt;br /&gt;
    GPIO_Init(GPIOC, &amp;amp;GPIOC_InitStructure);&lt;br /&gt;
&lt;br /&gt;
    RCC_MCO2Config(RCC_MCO2Source_SYSCLK, RCC_MCO2Div_4);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Die FPU===&lt;br /&gt;
====Allgemeines====&lt;br /&gt;
Damit die FPU richtig verwendet wird, müssen normalerweise zwei Bedingungen erfüllt sein:&lt;br /&gt;
&lt;br /&gt;
1. Der Controller muss in der Initialisierung-Funktion &#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; in &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; die FPU Hardware-seitig aktivieren&lt;br /&gt;
&lt;br /&gt;
2. Damit die FPU auch was zu tuen bekommt, müssen vom Compiler FPU-Instructions erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
Die Em::Blocks IDE verwendet standardmäßig die FPU, wenn eine Vorhanden ist. Hier wird die FPU Hardware-seitig aktiviert (&#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; Z.341):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* FPU settings ------------------------------------------------------------*/&lt;br /&gt;
  #if (__FPU_PRESENT == 1) &amp;amp;&amp;amp; (__FPU_USED == 1)&lt;br /&gt;
    SCB-&amp;gt;CPACR |= ((3UL &amp;lt;&amp;lt; 10*2)|(3UL &amp;lt;&amp;lt; 11*2));  /* set CP10 and CP11 Full Access */&lt;br /&gt;
  #endif&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
__FPU_PRESENT wird in der &#039;&#039;&#039;&#039;&#039;stm32f4xx.h&#039;&#039;&#039;&#039;&#039; definiert.&lt;br /&gt;
__FPU_USED wird von der IDE übernommen (siehe Build-Log): &#039;&#039;&#039;&#039;&#039;-D__FPU_USED&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Außerdem wird der Compiler von der IDE standardmäßig mit dem Argument &#039;&#039;&#039;&#039;&#039;-mfloat-abi=hard&#039;&#039;&#039;&#039;&#039; aufgerufen, wodurch FPU-Instructions erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
====FPU abschalten====&lt;br /&gt;
Um die FPU ab zu schalten (Mir würde jetzt nur Strom sparen als Grund einfallen) geht man wie folgt vor:&lt;br /&gt;
&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick Build options -&amp;gt; Device -&amp;gt; Policy&#039;&#039;&#039;&#039;&#039; wählt man &#039;&#039;&#039;&#039;&#039;Use target settings&#039;&#039;&#039;&#039;&#039; und über nimmt die Einstellungen, die vorher dort eingetragen waren, allerdings lässt man das Feld &#039;&#039;&#039;&#039;&#039;FP-hardware&#039;&#039;&#039;&#039;&#039; frei.&lt;br /&gt;
&lt;br /&gt;
[[Datei:fpu_1.png|FPU Abschalten Schritt 1]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;Compiler Settings -&amp;gt; Policy&#039;&#039;&#039;&#039;&#039; wählt man dann &#039;&#039;&#039;&#039;&#039;Use target options only&#039;&#039;&#039;&#039;&#039;. Dann kann man unter &#039;&#039;&#039;&#039;&#039;Categories&#039;&#039;&#039;&#039;&#039; die Option &#039;&#039;&#039;&#039;&#039;ARM FPU architecture&#039;&#039;&#039;&#039;&#039; auswählen. Dort stehen dann drei Möglichkeiten für die FPU zur Verfügung:&lt;br /&gt;
&lt;br /&gt;
1. Software-FPU-Library für Gleitkomma-Berechnung verwenden - Keine FPU-Instructions werden generiert (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=soft&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
2. Eine Mischung aus Software- und Hardware-FPU wird verwendet (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=softfp&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
3. Hardware-FPU wird für Gleitkomma-Berechnungen verwendet (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=hard&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
[[Datei:fpu_2.png|FPU Abschalten Schritt 2]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Um die FPU ab zu schalten wählt man natürlich die erste Möglichkeit.&lt;br /&gt;
Bei der 2. und 3. Möglichkeit fügt die IDE auch den Define &#039;&#039;&#039;&#039;&#039;__FPU_USED&#039;&#039;&#039;&#039;&#039; hinzu. Bei Der ersten Möglichkeit nicht. Der Code muss also nicht verändert / auskommentiert werden.&lt;br /&gt;
&lt;br /&gt;
Um die FPU wieder zu aktivieren müssen alle Schritte wieder rückgängig gemacht werden.&lt;br /&gt;
&lt;br /&gt;
Am besten ist es einfach mal alle Möglichkeiten im Einzelschritt durch zu probieren. Dann stellt man schnell fest, ob die FPU aktiviert wir oder nicht. Ein Blick in den erweiterten &#039;&#039;&#039;&#039;&#039;Build-Log&#039;&#039;&#039;&#039;&#039; gibt auch schnell Aufschluss darüber, wie der Compiler aufgerufen wird (siehe Kapitel [http://www.mikrocontroller.net/articles/STM32_-_Einstieg_mit_Em::Blocks#Compilieren Compilieren]).&lt;br /&gt;
&lt;br /&gt;
====Test Programm für die FPU====&lt;br /&gt;
Hier ein kleines Testprogramm, dass misst wie viele Taktzyklen für eine Gleitkomma-Multiplikation gebraucht werden. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define CORE_SysTickEn()    (*((u32*)0xE0001000)) = 0x40000001&lt;br /&gt;
#define CORE_SysTickDis()   (*((u32*)0xE0001000)) = 0x40000000&lt;br /&gt;
#define CORE_GetSysTick()   (*((u32*)0xE0001004))&lt;br /&gt;
&lt;br /&gt;
uint32_t t1, t2, dt;&lt;br /&gt;
float x, y, z;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    x = 53.64f;&lt;br /&gt;
    y = 0.27f;&lt;br /&gt;
&lt;br /&gt;
    CORE_SysTickEn();&lt;br /&gt;
    t1 = CORE_GetSysTick();&lt;br /&gt;
&lt;br /&gt;
    z = x * y;&lt;br /&gt;
&lt;br /&gt;
    t2 = CORE_GetSysTick();&lt;br /&gt;
    CORE_SysTickDis();&lt;br /&gt;
&lt;br /&gt;
    dt = t2 - t1;&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mein Ergebnis:&lt;br /&gt;
*Mit Hardware-FPU:  dt = 25&lt;br /&gt;
*Ohne Hardware-FPU: dt = 83&lt;br /&gt;
&lt;br /&gt;
Die Messung alleine braucht aber auch noch 9 Takt-Zyklen. Zum Vergleich reicht es aber.&lt;br /&gt;
&lt;br /&gt;
==Booten aus dem SRAM==&lt;br /&gt;
STM32 Controller haben die Möglichkeit Code aus dem Flash als auch aus dem SRAM auszuführen. Um eine Anwenung per Debugger in des SRAM zu laden sind nur wenige Schritte erforderlich:&lt;br /&gt;
&lt;br /&gt;
*Um das Linkerscript für den SRAM zu verwenden geht man zu: &#039;&#039;&#039;&#039;&#039;Build options... -&amp;gt; Device&#039;&#039;&#039;&#039;&#039; dort wählt man unter &#039;&#039;&#039;&#039;&#039;Policy&#039;&#039;&#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;Use target settings&#039;&#039;&#039;&#039;&#039; aus und übernimmt die vorherigen Einstellungen, nur unter &#039;&#039;&#039;&#039;&#039;Linker script*&#039;&#039;&#039;&#039;&#039; gibt man &#039;&#039;&#039;&#039;&#039;.\stm32f407vg_sram.ld&#039;&#039;&#039;&#039;&#039; an&lt;br /&gt;
&lt;br /&gt;
*Dann muss man noch unter &#039;&#039;&#039;&#039;&#039;Debug -&amp;gt; Interfaces -&amp;gt; Settings&#039;&#039;&#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;Vector table start&#039;&#039;&#039;&#039;&#039; auf 0x20000000 ändern und &#039;&#039;&#039;&#039;&#039;Execute from RAM&#039;&#039;&#039;&#039;&#039; auswählen.&lt;br /&gt;
&lt;br /&gt;
Anschließend kann man die Anwendung ganz normal debuggen. Nach einem Reset muss die Anwenung erneut mit dem Debugger gestartet werden.&lt;br /&gt;
&lt;br /&gt;
=Fortsetzung folgt..=&lt;br /&gt;
Kritik, Wünsche usw. sind gerne erwünscht, am besten hier in den Thread posten: [http://www.mikrocontroller.net/topic/323750 Neues STM32 Tutorial]&lt;br /&gt;
&lt;br /&gt;
[[Category:ARM]]&lt;br /&gt;
[[Category:STM32]]&lt;/div&gt;</summary>
		<author><name>Avrprogger</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=STM32_-_Einstieg_mit_Em::Blocks&amp;diff=81513</id>
		<title>STM32 - Einstieg mit Em::Blocks</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=STM32_-_Einstieg_mit_Em::Blocks&amp;diff=81513"/>
		<updated>2014-02-10T16:33:48Z</updated>

		<summary type="html">&lt;p&gt;Avrprogger: dg&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In diesem Tutorial werde ich versuchen, möglichst einfach, die ersten Schritte zur Entwicklung von STM32 Anwenungen mit der Em::Blocks IDE zu erklären. Hier soll nicht so stark auf die einzelnen Peripherie-Module der Controller eingegangen werden, sondern mehr auf die IDE und die verschieden Libraries, wie die CMSIS Library, die DSP-Library, die Standard-Peripheral-Library, die USB-Library und vllt. über Ethernet. Ich denke ein Kapitel zu FreeRTOS wird es auch geben. Auserdem steht im Vordergrund Sachen wie z.B. booten aus dem SRAM, In-Application-Programming, FPU, Core-Coupled-RAM usw. Mal sehn wie weit ich komme ;)&lt;br /&gt;
&lt;br /&gt;
==Die Entwicklungsumgebung==&lt;br /&gt;
===Hardware===&lt;br /&gt;
Zum testen der Anwendungen, benutze ich das STM32F4-Discovery Board, welches einen Debugger, Peripherie und natürlich einen STM32 Controller (STM32F407VGT6) enthält. Deshalb sind alle Beispiele hier für den STM32F407VG Controller ausgelegt, können aber meisten 1:1 auf andere Controller portiert werden. Ich werde auch möglichsts keine STM32F4-Discovery Board spezifischen Libraries verwenden, damit der Portierungs-Vorgang möglichsts einfach bleibt.&lt;br /&gt;
&lt;br /&gt;
===Software===&lt;br /&gt;
In diesem Tutorial verwende ich [http://www.emblocks.org/ Em::Blocks] als IDE. Em::Blocks ist eine kostenlose, uneingeschränkte IDE, die alle STM32 Mikrcontroller unterstützt und sehr einfach zu bedienen ist.&lt;br /&gt;
nach dem Download kann die IDE per Dialog, sehr einfach, installiert werden. Als Compiler beinhaltet Em::Blocks den &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
Die IDE unterstützt zurzeit den ST-Link, den J-Link und es gibt eine Generic-Vorlage, durch welche andere Debugger konfiguriert werden können.&lt;br /&gt;
&lt;br /&gt;
Außerdem muss noch der passende Treiber für den Debugger installiert werden. Verwendet man ein Discovery-Board muss der [http://www.st.com/web/catalog/tools/FM146/CL1984/SC724/SS1677/PF251168 ST-Link/V2]-Treiber heruntergeladen und installiert werden. (Die Installation muss evtl. als Administrator ausgeführt werden, da sonst die Installation unvollständig wird.) Nach der Installation des Treibers kann man den Debugger über die entsprechende USB Schnittstelle an den PC anschließen und es sollte die Meldung von Windows kommen, dass der richtige Treiber gefunden wurde.&lt;br /&gt;
&lt;br /&gt;
===Libraries===&lt;br /&gt;
Zum programmieren benötigt man noch die [http://www.arm.com/products/processors/cortex-m/cortex-microcontroller-software-interface-standard.php CMSIS] und die Standard-Peripheral-Library (z.B. für die F4 Controller [http://www.st.com/stonline/stappl/productcatalog/app?page=partNumberSearchPage&amp;amp;levelid=SS1577&amp;amp;parentid=1743&amp;amp;resourcetype=SW Standard-Peripheral-Library-F4]), die man am besten in einen Ordner (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\STM32&#039;&#039;&#039;&#039;&#039;) entpackt&lt;br /&gt;
&lt;br /&gt;
==Basis-Wissen zur IDE==&lt;br /&gt;
Einige Grundfunktionalitäten der IDE:&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von Dateien zum Projekt===&lt;br /&gt;
Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf &amp;lt;ProjektName&amp;gt; -&amp;gt; Add files...&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Enfernen von Dateien aus dem Projekt===&lt;br /&gt;
Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf die Datei / mehrere Dateien auswählen -&amp;gt; Remove file from project&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
Die Dateien werden lediglich aus dem Projekt entfernt und nicht von der Festplatte gelöscht.&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von Include-Pfaden===&lt;br /&gt;
Sofern die Include-Datei(en) nicht im standard Include-Ordner &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; des Projektes liegen, muss man den Pfad zum Projekt hinzufügen, damit der Compiler die Include-Dateien später auch finden kann. Man geht wie folgt vor: Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf &amp;lt;ProjektName&amp;gt; -&amp;gt; Build options... -&amp;gt; Search Directories -&amp;gt; Add&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Compilieren===&lt;br /&gt;
Entweder über das &#039;&#039;&#039;&#039;&#039;Build&#039;&#039;&#039;&#039;&#039; Menü oder über &#039;&#039;&#039;&#039;&#039;F7&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Um eine genau Ausgabe des Compiler-Aufrufes mit allen Argumenten zu bekommen, geht man im &#039;&#039;&#039;&#039;&#039;Settings&#039;&#039;&#039;&#039;&#039; Menü auf &#039;&#039;&#039;&#039;&#039;Tools...&#039;&#039;&#039;&#039;&#039; und dann auf &#039;&#039;&#039;&#039;&#039;Toolchain executables&#039;&#039;&#039;&#039;&#039;. Ganz unten, unter &#039;&#039;&#039;&#039;&#039;Logging&#039;&#039;&#039;&#039;&#039; kann man dann &#039;&#039;&#039;&#039;&#039;Full command line&#039;&#039;&#039;&#039;&#039; auswählen.&lt;br /&gt;
&lt;br /&gt;
===Debuggen===&lt;br /&gt;
*Als erstes den Debugger starten über das &#039;&#039;&#039;&#039;&#039;Debug&#039;&#039;&#039;&#039;&#039; Menü und &#039;&#039;&#039;&#039;&#039;Start/stop Debug Session&#039;&#039;&#039;&#039;&#039; oder über &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
*Danach läuft die Anwendung auf dem Controller und warten im &#039;&#039;&#039;&#039;&#039;Reset_Handler&#039;&#039;&#039;&#039;&#039; auf Einzelschritt- bzw. Run- Befehle (&#039;&#039;&#039;&#039;&#039;F5, F10, F11&#039;&#039;&#039;&#039;&#039; usw..(siehe &#039;&#039;&#039;&#039;&#039;Debug-Menü&#039;&#039;&#039;&#039;&#039; für alle Möglichkeiten))&lt;br /&gt;
&lt;br /&gt;
*Mit &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039; wird die Debug-Session auch wieder beendet&lt;br /&gt;
&lt;br /&gt;
*Unter &#039;&#039;&#039;&#039;&#039;Debug -&amp;gt; Interfaces -&amp;gt; Target settings&#039;&#039;&#039;&#039;&#039; können Eigenschaften, wie z.B &#039;&#039;&#039;&#039;&#039;Run to main()&#039;&#039;&#039;&#039;&#039; aktiviert werden.&lt;br /&gt;
&lt;br /&gt;
===Projekt als Template abspeichern===&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;File -&amp;gt; Save project as template...&#039;&#039;&#039;&#039;&#039;. Das Template erscheint dann im Projekt-Dialog unter &#039;&#039;&#039;&#039;&#039;User templates&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Das erste Projekt erstellen==&lt;br /&gt;
Hier erkläre ich, wie man am Besten (aus meiner Sicht), ein neues Projekt von Grund auf erstellt, sodass man hinterher, den Controller-Kern über die CMSIS-Library und die Peripherie über die Register steuern kann.&lt;br /&gt;
&lt;br /&gt;
===1. Projekt mit der IDE erstellen===&lt;br /&gt;
Nach der Installation der oben beschriebenen Komponenten erstellt man am besten ein Verzeichnis (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\EmBlocks&#039;&#039;&#039;&#039;&#039;), indem später alle Projekte gespeichert werden. Für Libraries kann man auch noch ein Verzeichnis (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\STM32&#039;&#039;&#039;&#039;&#039;) erstellen, wo alle Libraries gespeichert werden, die man für die Projekt brauchen.&lt;br /&gt;
&lt;br /&gt;
Als nächstes starten man EmBlocks. Bei dem ersten Start öffnet sich ein Fenster, wo verschiedene Compiler angezeigt werden, die Em::Blocks findet. Dort wählt man den &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039; aus und klickt &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039;. Nun sollte sich das Hauptfenster von Em::Blocks öffnen. Über &#039;&#039;&#039;&#039;&#039;Create a new Project&#039;&#039;&#039;&#039;&#039; oder &#039;&#039;&#039;&#039;&#039;File -&amp;gt; New -&amp;gt; Project&#039;&#039;&#039;&#039;&#039; ruft man den Projekt-Dialog auf und kann ein neues Projekt erzeugen.&lt;br /&gt;
&lt;br /&gt;
Auf der Ersten Seite wählen man den &#039;&#039;&#039;&#039;&#039;STmicro-ARM&#039;&#039;&#039;&#039;&#039; Projekt-Typ aus.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_1.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auf der nächsten Seite wird man darauf hingewiesen, dass das der entsprechende Projekt-Typ-Dialog ausgeführt wird. Hier kann man ein Häkchen bei &#039;&#039;&#039;&#039;&#039;Skip this page next time&#039;&#039;&#039;&#039;&#039; setzen und auf &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; klicken.&lt;br /&gt;
&lt;br /&gt;
Im nächsten Schritt wählen man das zuvor erstellt Verzeichnis unter &#039;&#039;&#039;&#039;&#039;Folder to create Project in&#039;&#039;&#039;&#039;&#039; aus, indem später alle Projekt gespeichert werden. Außerdem geben wir dem Projekt einen Namen (z.B. &#039;&#039;&#039;&#039;&#039;FirstProject&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_2.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danach muss man einen Compiler auswählen und bestimmen, welche Projekt-Konfigurationen erszeugt werden sollen. Unter &#039;&#039;&#039;&#039;&#039;Compiler&#039;&#039;&#039;&#039;&#039; wählt man &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039; und man kann das Häkchen bei &#039;&#039;&#039;&#039;&#039;Create &amp;quot;Release&amp;quot; configuration&#039;&#039;&#039;&#039;&#039; entfernen, da diese unnötig ist, die Debug-Konfiguration sollte eig. immer ausreichen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_3.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auf den folgenden Seite wird der Controller ausgewählt. Verwendet man ein STM32F4-Discovery Board müssen folgende Dinge gewählt werden: &#039;&#039;&#039;&#039;&#039;Cortex_M4 (F3xx - F4xx) -&amp;gt; STM32F4xx (Cortex M4 with FPU) -&amp;gt; STM32F407VG&#039;&#039;&#039;&#039;&#039;. Leider sind die Auswahl Möglichkeiten nicht ganz richtig, da auch die F3 Controller einen Cortex M4 Kern und eine FPU haben (Ist aber nicht so wichtig, ist nur eine formale Sache). Außerdem entfernt man das Häkchen bei &#039;&#039;&#039;&#039;&#039;Standard Peripherals Library&#039;&#039;&#039;&#039;&#039; (Wie man die Standard-Peripheral-Library einbindet und verwendet erkläre ich später). Man kann auch das Häkchen bei &#039;&#039;&#039;&#039;&#039;Create hex file for Realease target&#039;&#039;&#039;&#039;&#039; entfernen.&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;Stack Size&#039;&#039;&#039;&#039;&#039; und &#039;&#039;&#039;&#039;&#039;Heap Size&#039;&#039;&#039;&#039;&#039; wird die Größe von Stack und Heap festgelegt. Für eine erste Anwendung kann man die Einstellungen so lassen (Stack-Size: 0x0100 =&amp;gt; 256 Byte Stack und Heap-Size: 0x0000 =&amp;gt; kein Heap). Mit &#039;&#039;&#039;&#039;&#039;Finish&#039;&#039;&#039;&#039;&#039; ist der Projekt Dialog abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_4.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danach sollten sich zwei neue Fenster öffnen, um die Debug-Eigenschaften fest zu legen.&lt;br /&gt;
Verwendet man ein Discovery Board/ST-Link müssen die Einstellungen wie auf dem Bild gewählt werden. Über den Button &#039;&#039;&#039;&#039;&#039;Settings&#039;&#039;&#039;&#039;&#039; öffnet sich das zweite Fenster, falls sich dieses nicht schon von alleine öffnen sollte. Nach den Schließen der Fenster über &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; ist der Projekt Dialog beendet und ein neues Projekt steht zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_5_1.png|Debug Eigenschaften 1. Fenster]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_5_2.png|Debug Eigenschaften 2. Fenster]]&lt;br /&gt;
&lt;br /&gt;
===2. CMSIS-Library und Startup-Code hinzufügen===&lt;br /&gt;
Wenn man sich, nachdem man ein neues Projekt in der IDE erstellt hat, die bereits vorhandenen Dateien im Projekt ansieht, stellt man fest, das bereits ein Ordner &#039;&#039;&#039;&#039;&#039;cmsis&#039;&#039;&#039;&#039;&#039; existiert, der einige wichtige Include-Dateien der CMSIS-Library enthält. Allerdings sind das wirklich nur die wichtigsten Include-Dateien der CMSIS-Library und dazu noch, die aus einer älternen Version. Ich ziehe es deshalb vor die &amp;quot;Mini-CMSIS-Libraray&amp;quot; und die &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c/.h&#039;&#039;&#039;&#039;&#039; Dateien des Projektes durch aktuellere Versionen zu ersetzen. So ist später auch die Integration  von anderen Libraries, wie z.B. der CMSIS-DSP-Libarary einfacher.  &lt;br /&gt;
&lt;br /&gt;
Zunächst gehen man in das Projekt-Verzeichnis und löscht:&lt;br /&gt;
*Den Ordner &#039;&#039;&#039;&#039;&#039;cmsis&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Alle Dateien im Include Verzeichnis &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; im &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner&lt;br /&gt;
&lt;br /&gt;
Außerdem entfernt man auch alle gelöschten Dateien in der IDE aus dem Projekt mit &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Rechts Klick -&amp;gt; Remove file from project&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Es sollte folgende Verzeichnis Struktur überbleiben:&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_6.png|Überbleibende Dateien]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Jetzt müssen die gelöschten Dateien durch die aktuelleren ersetzt werden.&lt;br /&gt;
&lt;br /&gt;
*Dazu kopieren man den gesamten Ordner &#039;&#039;&#039;&#039;&#039;CMSIS&#039;&#039;&#039;&#039;&#039; aus dem CMSIS Download in das Projekt Verzeichnis.&lt;br /&gt;
&lt;br /&gt;
*Aus dem Standard-Peripheral-Library Download kopiert man von &#039;&#039;&#039;&#039;&#039;Libraries\CMSIS\Device\ST\STM32F4xx\Include&#039;&#039;&#039;&#039;&#039; alle Dateien in den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projekt Verzeichnisses&lt;br /&gt;
&lt;br /&gt;
*Aus der Standard-Peripheral-Library kopieren man ebenfalls von &#039;&#039;&#039;&#039;&#039;Libraries\CMSIS\Device\ST\STM32F4xx\Source\Templates&#039;&#039;&#039;&#039;&#039; die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; in den &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner des Projekts&lt;br /&gt;
&lt;br /&gt;
Anschließend müssen die neuen Dateien in der IDE dem Projekt hinzugefügt werden. Dazu benutzt man &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Rechts Klick -&amp;gt; Add files&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
*Aus dem &#039;&#039;&#039;&#039;&#039;CMSIS&#039;&#039;&#039;&#039;&#039; Ordner im Projekt Verzeichnis werden aus den Unterorder &#039;&#039;&#039;&#039;&#039;Include&#039;&#039;&#039;&#039;&#039; folgende Dateien dem Projekt hinzugefügt:&lt;br /&gt;
**arm_common_tables.h&lt;br /&gt;
**arm_const_structs.h&lt;br /&gt;
**arm_math.h&lt;br /&gt;
**core_cm4.h&lt;br /&gt;
**core_cm4_simd.h&lt;br /&gt;
**core_cmFunc.h&lt;br /&gt;
**core_cmInstr.h&lt;br /&gt;
*Alle Dateien aus den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projektes&lt;br /&gt;
*Die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; aus dem &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner&lt;br /&gt;
&lt;br /&gt;
So sollte die Struktur dann aussehen:&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_7.png|Anwenungs-Grundgerüst]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Da einige Dateien der Libraries später bearbeitet werden müssen und Schreibgeschützt sind, weise ich hier schonmal darauf hin, das der Schreibschutz in der IDE über &#039;&#039;&#039;&#039;&#039;Rechts Klick auf die Datei -&amp;gt; Properties -&amp;gt; Häkchen bei &amp;quot;File is read only&amp;quot; entfernen&#039;&#039;&#039;&#039;&#039; entfert werden kann.&lt;br /&gt;
&lt;br /&gt;
Damit die IDE die Header-Dateien der CMSIS Library auch finden kann, weil diese ja nicht im standard Include Ordner &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; liegen, muss unter &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Build Options -&amp;gt; Search Directories&#039;&#039;&#039;&#039;&#039; der Pfad &#039;&#039;&#039;&#039;&#039;CMSIS\Include&#039;&#039;&#039;&#039;&#039; hinzugefügt werden.&lt;br /&gt;
&lt;br /&gt;
Compiliert man jetzt das Projekt mit &#039;&#039;&#039;&#039;&#039;F7&#039;&#039;&#039;&#039;&#039; gibt es ein paar Fehler Meldungen, weil keine Controller-Reihe ausgewählt wurde. Ebenfalls unter &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Build Options -&amp;gt; Compiler Settings -&amp;gt; #defines&#039;&#039;&#039;&#039;&#039; wird der Define &#039;&#039;&#039;&#039;&#039;STM32F40_41xxx&#039;&#039;&#039;&#039;&#039; hinzugefügt.&lt;br /&gt;
&lt;br /&gt;
Beim erneuten Compilieren sollten sich nun keine neuen Fehler ergeben.&lt;br /&gt;
&lt;br /&gt;
===Das erste Programm===&lt;br /&gt;
Nachdem ein grundsätzliches &amp;quot;Gerüst&amp;quot; fertig ist, kann man den ersten Code schreiben.&lt;br /&gt;
main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC-&amp;gt;AHB1ENR |= RCC_AHB1ENR_GPIODEN;    //Takt für GPIO aktivieren&lt;br /&gt;
    GPIOD-&amp;gt;MODER |= GPIO_MODER_MODER15_0;   //GPIOD Pin15 als Ausgang&lt;br /&gt;
    GPIOD-&amp;gt;BSRRL |= GPIO_BSRR_BS_15;        //GPIOD Pin15 auf High ziehen&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039; wird dann der Debugger gestartet. Hat der Debugger das Projekt erfolgreich übertragen kann die Ausführung mit &#039;&#039;&#039;&#039;&#039;F5&#039;&#039;&#039;&#039;&#039; begonnen werden.&lt;br /&gt;
&lt;br /&gt;
==Libraries einbinden/verwenden==&lt;br /&gt;
===Einbinden der Standard-Peripheral-Library===&lt;br /&gt;
Um nicht immer die einzelnen Register, wie im ersten &amp;quot;bare-metal&amp;quot; Beispiel, aus dem Reference-Manual zu suchen und zu beschreiben, gibt es von ST die Standard Peripheral Library, die diese Aufgaben übernimmt und mit der sich die &amp;quot;normale/grundlegende&amp;quot; (Alles außer USB und Ethernet) Peripherie recht einfach steuern lässt. Um die Library zu verwenden erzeugt man wie oben beschrieben ein neues Grundgerüst und kopiert als erstes den Ordner &#039;&#039;&#039;&#039;&#039;Libraries\STM32F4xx_StdPeriph_Driver&#039;&#039;&#039;&#039;&#039; aus dem Standard-Peripheral-Library Download in das Projekt-Verzeichnis. Außerdem muss man die Datei &#039;&#039;&#039;&#039;&#039;Project\STM32F4xx_StdPeriph_Templates\stm32f4xx_conf.h&#039;&#039;&#039;&#039;&#039; ebenfalls aus dem Standard-Peripheral-Library Download in den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projektes kopieren. In der IDE fügt man den Include-Path &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\inc&#039;&#039;&#039;&#039;&#039; hinzufügen, wie bei der CMSIS-Library (s.o.).&lt;br /&gt;
Außerdem muss noch &#039;&#039;&#039;&#039;&#039;USE_STDPERIPH_DRIVER&#039;&#039;&#039;&#039;&#039; als Define in der IDE hinzugefügt werden (s.o.).&lt;br /&gt;
Danach fügt man die Source- und Include-Dateien aus dem Ordner &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\inc&#039;&#039;&#039;&#039;&#039; und &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\src&#039;&#039;&#039;&#039;&#039; dem Project mit &#039;&#039;&#039;&#039;&#039;&amp;lt;Project Name&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Add files&#039;&#039;&#039;&#039;&#039; hinzu, allerdings nur die, für welche auch der Controller die entsprechende Peripherie besitzt. Beim STM32F4-Discovery Board / STM32F407VG Controller dürfen also nicht folgende Dateien nicht mit hinzugefügt werden, weil diese Peripherie nur bei anderen Controller vorhanden ist:&lt;br /&gt;
&lt;br /&gt;
*stm32f4xx_dma2d.c/.h&lt;br /&gt;
*stm32f4xx_fmc.c/.h&lt;br /&gt;
*stm32f4xx_ltdc.c/.h&lt;br /&gt;
*stm32f4xx_sai.c/.h&lt;br /&gt;
&lt;br /&gt;
Daraus resultiert folgende Struktur:&lt;br /&gt;
&lt;br /&gt;
[[Datei:stdperiphlib_2.png|Header-Struktur]] [[Datei:stdperiphlib_1.png|Source-Struktur]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Anschließen kann die Standard-Peripheral-Library benutz werden.&lt;br /&gt;
main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);&lt;br /&gt;
&lt;br /&gt;
    GPIO_InitTypeDef GPIOD_InitStructure;&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Mode = GPIO_Mode_OUT;     //Als Ausgang&lt;br /&gt;
    GPIOD_InitStructure.GPIO_OType = GPIO_OType_PP;    //Push-Pull Betrieb&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Pin = GPIO_Pin_15;        //Pin 15 (STM32F4-Discovery: Blaue LED)&lt;br /&gt;
    GPIOD_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;  //Kein Pull-Up oder Pull-Down Widerstand aktiviert&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Speed = GPIO_Speed_25MHz; //25MHz Update-Rate&lt;br /&gt;
    GPIO_Init(GPIOD, &amp;amp;GPIOD_InitStructure);&lt;br /&gt;
&lt;br /&gt;
    GPIO_SetBits(GPIOD, GPIO_Pin_15);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Startup-Code, Linker-Script, Takt, FPU usw.==&lt;br /&gt;
===Startup-Code===&lt;br /&gt;
Em::Blocks fügt standardmäßig einen Startup-Code mit in das Projekt ein. Die wichtigsten Dinge die darin erledigt werden sind folgende:&lt;br /&gt;
&lt;br /&gt;
*Stack und Heap wird angelgt&lt;br /&gt;
*Die Vector-Table wird angelegt&lt;br /&gt;
*Ein Default Reset-Handler wird implementiert, dieser erledigt folgende aufgaben:&lt;br /&gt;
**Kopieren der definierten Daten aus dem Flash in den SRAM&lt;br /&gt;
**&#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; wird aufgerfen, wenn &#039;&#039;&#039;&#039;&#039;__NO_SYSTEM_INIT&#039;&#039;&#039;&#039;&#039; nicht definiert ist&lt;br /&gt;
**Sprung in die &#039;&#039;&#039;&#039;&#039;main()&#039;&#039;&#039;&#039;&#039; Funktion&lt;br /&gt;
*Allen anderen Interrupt-Handler wird eine Default-Funktion &#039;&#039;&#039;&#039;&#039;def_irq_handler&#039;&#039;&#039;&#039;&#039; mit einer &#039;&#039;&#039;&#039;&#039;while(1)&#039;&#039;&#039;&#039;&#039;-Schleife zugewiesen, falls kein anderer Interrupt-Handler existiert.&lt;br /&gt;
&lt;br /&gt;
Normalerweise muss am Startup-Code nichts verändert werden.&lt;br /&gt;
&lt;br /&gt;
===Linker-Script===&lt;br /&gt;
Em::Blocks stellt zwei fertige Linker-Scripts bereit, eins für die Ausführung des Programmes aus dem Flash (&#039;&#039;&#039;&#039;&#039;*_flash.ld&#039;&#039;&#039;&#039;&#039;), das andere für die Ausführung aus dem SRAM (&#039;&#039;&#039;&#039;&#039;*_sram.ld&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Normalerweise muss auch hier nichts geändert werden, es sei den Daten sollen in bestimmten Adressbereichen abgelegt werden (z.B. im Core-Coupled RAM), was ich später noch zum Tutorial hinzufüge.&lt;br /&gt;
&lt;br /&gt;
===Der Takt===&lt;br /&gt;
Jeder Controller oder Prozessor braucht einen Takt, indem er die einzelnen Maschinen-Befehle abarbeiten kann.&lt;br /&gt;
Bei den STM32 Mikrocontrollern kann dieser Takt aus verschiedenen Quellen kommen:&lt;br /&gt;
&lt;br /&gt;
1. High Speed Internal Oszillator (HSI)&lt;br /&gt;
&lt;br /&gt;
2. High Speed External Oszillator (HSE)&lt;br /&gt;
&lt;br /&gt;
3. Low Speed Internal Oszillator (LSI)&lt;br /&gt;
&lt;br /&gt;
4. Low Speed External Oszillator (LSE)&lt;br /&gt;
&lt;br /&gt;
5. Phase-Locked Loop (PLL) (generiert den Takt aus den ersten vier Taktquellen durch Teiler und Faktoren)&lt;br /&gt;
&lt;br /&gt;
Nach einem Reset wird der Controller aus der HSI Taktquelle versorgt (16MHz beim STM32F407VG). Um die voll Performance des Controllers zu erreichen muss die PLL verwendet werden, welche den Takt durch geschickte Teiler und Faktoren vervielfältigt, sodass am Ende der Controller mit der maximalen Taktfrequenz läuft. Die notwendige Initialisierung der PLL findet in der Funktion &#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; statt. Die PLL erzeugt zunächst einen Basistakt:&lt;br /&gt;
&lt;br /&gt;
PLL_VCO = (F_HSE / PLL_M) * PLL_N&lt;br /&gt;
&lt;br /&gt;
Aus diesem Takt wird dann der Takt für den Controller-Kern abgeleitet:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = PLL_VCO / PLL_P&lt;br /&gt;
&lt;br /&gt;
Und der Takt für SDIO / USB / RNG (48MHz):&lt;br /&gt;
&lt;br /&gt;
48MHz = PLL_VCO / PLL_Q&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Durch weiter Teiler werden, die Takte für die einzelnen Busse erzeugt, da diese nicht alle beliebig schnell betrieben werden dürfen.&lt;br /&gt;
&lt;br /&gt;
Genaue Angaben findet man zu dem jeweiligen Clock-System des Controllers im Reference Manual.&lt;br /&gt;
&lt;br /&gt;
Ein Blick in den &amp;quot;Kommentar-Header&amp;quot; verrät, dass von einem externen (HSE) Oszillator von 25MHz ausgegangen wird, der die PLL versorgen soll.&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((25MHz / PLL_M(25)) * PLL_N(336)) / PLL_P(2) = 168MHz&lt;br /&gt;
&lt;br /&gt;
Allerdings stimmt diese Rechnung natürlich nur, wenn wirklich ein 25MHz Quarz am Controller angeschlossen ist. Auf dem STM32F4-Discovery Board befindet sich aber nur ein 8MHz Quarz. Demnach gilt:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((8MHz / PLL_M(25)) * PLL_N(336)) / PLL_P(2) = 53.76MHz&lt;br /&gt;
&lt;br /&gt;
Der Controller läuft also nur mit 53.76MHz, wenn wie ober beschrieben ein Projekt erstellt wird. Allerdings kann dieses Problem durch ändern von den betroffen Defines behoben werden:&lt;br /&gt;
 &lt;br /&gt;
*Dazu geht man in die &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; Datei und passt zur Vollständigkeit erstmal die zum Controller passende Tabelle im &amp;quot;Kommentar-Header&amp;quot; an (Z.57f):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      HSE Frequency(Hz)                      | 8000000&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      PLL_M                                  | 8&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Danach passt man den PPL_M Define (Z.254) an:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/************************* PLL Parameters *************************************/&lt;br /&gt;
/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */&lt;br /&gt;
#define PLL_M      8&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Außerdem muss man den HSE_VALUE Define in der &#039;&#039;&#039;&#039;&#039;inc/stm32f4xx.h&#039;&#039;&#039;&#039;&#039; angepasst werden (Z.122):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#if !defined  (HSE_VALUE)&lt;br /&gt;
  #define HSE_VALUE    ((uint32_t)8000000) /*!&amp;lt; Value of the External oscillator in Hz */&lt;br /&gt;
&lt;br /&gt;
#endif /* HSE_VALUE */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine neue Berechnung zeigt:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((8MHz / PLL_M(8)) * PLL_N(336)) / PLL_P(2) = 168MHz&lt;br /&gt;
&lt;br /&gt;
Jetzt läuft der Controller mit maximaler Geschwindigkeit.&lt;br /&gt;
&lt;br /&gt;
Die Theorie wird durch folgendes Programm verifiziert. Der geviertelte System-Takt SYSCLK wir am Pin PC9 ausgegeben. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);&lt;br /&gt;
&lt;br /&gt;
    GPIO_InitTypeDef GPIOC_InitStructure;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Mode = GPIO_Mode_AF;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_OType = GPIO_OType_PP;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Pin = GPIO_Pin_9;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;&lt;br /&gt;
    GPIO_Init(GPIOC, &amp;amp;GPIOC_InitStructure);&lt;br /&gt;
&lt;br /&gt;
    RCC_MCO2Config(RCC_MCO2Source_SYSCLK, RCC_MCO2Div_4);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Die FPU===&lt;br /&gt;
====Allgemeines====&lt;br /&gt;
Damit die FPU richtig verwendet wird, müssen normalerweise zwei Bedingungen erfüllt sein:&lt;br /&gt;
&lt;br /&gt;
1. Der Controller muss in der Initialisierung-Funktion &#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; in &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; die FPU Hardware-seitig aktivieren&lt;br /&gt;
&lt;br /&gt;
2. Damit die FPU auch was zu tuen bekommt, müssen vom Compiler FPU-Instructions erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
Die Em::Blocks IDE verwendet standardmäßig die FPU, wenn eine Vorhanden ist. Hier wird die FPU Hardware-seitig aktiviert (&#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; Z.341):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* FPU settings ------------------------------------------------------------*/&lt;br /&gt;
  #if (__FPU_PRESENT == 1) &amp;amp;&amp;amp; (__FPU_USED == 1)&lt;br /&gt;
    SCB-&amp;gt;CPACR |= ((3UL &amp;lt;&amp;lt; 10*2)|(3UL &amp;lt;&amp;lt; 11*2));  /* set CP10 and CP11 Full Access */&lt;br /&gt;
  #endif&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
__FPU_PRESENT wird in der &#039;&#039;&#039;&#039;&#039;stm32f4xx.h&#039;&#039;&#039;&#039;&#039; definiert.&lt;br /&gt;
__FPU_USED wird von der IDE übernommen (siehe Build-Log): &#039;&#039;&#039;&#039;&#039;-D__FPU_USED&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Außerdem wird der Compiler von der IDE standardmäßig mit dem Argument &#039;&#039;&#039;&#039;&#039;-mfloat-abi=hard&#039;&#039;&#039;&#039;&#039; aufgerufen, wodurch FPU-Instructions erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
====FPU abschalten====&lt;br /&gt;
Um die FPU ab zu schalten (Mir würde jetzt nur Strom sparen als Grund einfallen) geht man wie folgt vor:&lt;br /&gt;
&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick Build options -&amp;gt; Device -&amp;gt; Policy&#039;&#039;&#039;&#039;&#039; wählt man &#039;&#039;&#039;&#039;&#039;Use target settings&#039;&#039;&#039;&#039;&#039; und über nimmt die Einstellungen, die vorher dort eingetragen waren, allerdings lässt man das Feld &#039;&#039;&#039;&#039;&#039;FP-hardware&#039;&#039;&#039;&#039;&#039; frei.&lt;br /&gt;
&lt;br /&gt;
[[Datei:fpu_1.png|FPU Abschalten Schritt 1]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;Compiler Settings -&amp;gt; Policy&#039;&#039;&#039;&#039;&#039; wählt man dann &#039;&#039;&#039;&#039;&#039;Use target options only&#039;&#039;&#039;&#039;&#039;. Dann kann man unter &#039;&#039;&#039;&#039;&#039;Categories&#039;&#039;&#039;&#039;&#039; die Option &#039;&#039;&#039;&#039;&#039;ARM FPU architecture&#039;&#039;&#039;&#039;&#039; auswählen. Dort stehen dann drei Möglichkeiten für die FPU zur Verfügung:&lt;br /&gt;
&lt;br /&gt;
1. Software-FPU-Library für Gleitkomma-Berechnung verwenden - Keine FPU-Instructions werden generiert (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=soft&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
2. Eine Mischung aus Software- und Hardware-FPU wird verwendet (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=softfp&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
3. Hardware-FPU wird für Gleitkomma-Berechnungen verwendet (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=hard&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
[[Datei:fpu_2.png|FPU Abschalten Schritt 2]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Um die FPU ab zu schalten wählt man natürlich die erste Möglichkeit.&lt;br /&gt;
Bei der 2. und 3. Möglichkeit fügt die IDE auch den Define &#039;&#039;&#039;&#039;&#039;__FPU_USED&#039;&#039;&#039;&#039;&#039; hinzu. Bei Der ersten Möglichkeit nicht. Der Code muss also nicht verändert / auskommentiert werden.&lt;br /&gt;
&lt;br /&gt;
Um die FPU wieder zu aktivieren müssen alle Schritte wieder rückgängig gemacht werden.&lt;br /&gt;
&lt;br /&gt;
Am besten ist es einfach mal alle Möglichkeiten im Einzelschritt durch zu probieren. Dann stellt man schnell fest, ob die FPU aktiviert wir oder nicht. Ein Blick in den erweiterten &#039;&#039;&#039;&#039;&#039;Build-Log&#039;&#039;&#039;&#039;&#039; gibt auch schnell Aufschluss darüber, wie der Compiler aufgerufen wird (siehe Kapitel [http://www.mikrocontroller.net/articles/STM32_-_Einstieg_mit_Em::Blocks#Compilieren Compilieren]).&lt;br /&gt;
&lt;br /&gt;
====Test Programm für die FPU====&lt;br /&gt;
Hier ein kleines Testprogramm, dass misst wie viele Taktzyklen für eine Gleitkomma-Multiplikation gebraucht werden. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define CORE_SysTickEn()    (*((u32*)0xE0001000)) = 0x40000001&lt;br /&gt;
#define CORE_SysTickDis()   (*((u32*)0xE0001000)) = 0x40000000&lt;br /&gt;
#define CORE_GetSysTick()   (*((u32*)0xE0001004))&lt;br /&gt;
&lt;br /&gt;
uint32_t t1, t2, dt;&lt;br /&gt;
float x, y, z;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    x = 53.64f;&lt;br /&gt;
    y = 0.27f;&lt;br /&gt;
&lt;br /&gt;
    CORE_SysTickEn();&lt;br /&gt;
    t1 = CORE_GetSysTick();&lt;br /&gt;
&lt;br /&gt;
    z = x * y;&lt;br /&gt;
&lt;br /&gt;
    t2 = CORE_GetSysTick();&lt;br /&gt;
    CORE_SysTickDis();&lt;br /&gt;
&lt;br /&gt;
    dt = t2 - t1;&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mein Ergebnis:&lt;br /&gt;
*Mit Hardware-FPU:  dt = 25&lt;br /&gt;
*Ohne Hardware-FPU: dt = 83&lt;br /&gt;
&lt;br /&gt;
==Booten aus dem SRAM==&lt;br /&gt;
STM32 Controller haben die Möglichkeit Code aus dem Flash als auch aus dem SRAM auszuführen. Um eine Anwenung per Debugger in des SRAM zu laden sind nur wenige Schritte erforderlich:&lt;br /&gt;
&lt;br /&gt;
*Um das Linkerscript für den SRAM zu verwenden geht man zu: &#039;&#039;&#039;&#039;&#039;Build options... -&amp;gt; Device&#039;&#039;&#039;&#039;&#039; dort wählt man unter &#039;&#039;&#039;&#039;&#039;Policy&#039;&#039;&#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;Use target settings&#039;&#039;&#039;&#039;&#039; aus und übernimmt die vorherigen Einstellungen, nur unter &#039;&#039;&#039;&#039;&#039;Linker script*&#039;&#039;&#039;&#039;&#039; gibt man &#039;&#039;&#039;&#039;&#039;.\stm32f407vg_sram.ld&#039;&#039;&#039;&#039;&#039; an&lt;br /&gt;
&lt;br /&gt;
*Dann muss man noch unter &#039;&#039;&#039;&#039;&#039;Debug -&amp;gt; Interfaces -&amp;gt; Settings&#039;&#039;&#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;Vector table start&#039;&#039;&#039;&#039;&#039; auf 0x20000000 ändern und &#039;&#039;&#039;&#039;&#039;Execute from RAM&#039;&#039;&#039;&#039;&#039; auswählen.&lt;br /&gt;
&lt;br /&gt;
Anschließend kann man die Anwendung ganz normal debuggen. Nach einem Reset muss die Anwenung erneut mit dem Debugger gestartet werden.&lt;br /&gt;
&lt;br /&gt;
=Fortsetzung folgt..=&lt;br /&gt;
Kritik, Wünsche usw. sind gerne erwünscht, am besten hier in den Thread posten: [http://www.mikrocontroller.net/topic/323750 Neues STM32 Tutorial]&lt;br /&gt;
&lt;br /&gt;
[[Category:ARM]]&lt;br /&gt;
[[Category:STM32]]&lt;/div&gt;</summary>
		<author><name>Avrprogger</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=STM32_-_Einstieg_mit_Em::Blocks&amp;diff=81512</id>
		<title>STM32 - Einstieg mit Em::Blocks</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=STM32_-_Einstieg_mit_Em::Blocks&amp;diff=81512"/>
		<updated>2014-02-10T16:29:13Z</updated>

		<summary type="html">&lt;p&gt;Avrprogger: fd&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In diesem Tutorial werde ich versuchen, möglichst einfach, die ersten Schritte zur Entwicklung von STM32 Anwenungen mit der Em::Blocks IDE zu erklären. Hier soll nicht so stark auf die einzelnen Peripherie-Module der Controller eingegangen werden, sondern mehr auf die IDE und die verschieden Libraries, wie die CMSIS Library, die DSP-Library, die Standard-Peripheral-Library, die USB-Library und vllt. über Ethernet. Ich denke ein Kapitel zu FreeRTOS wird es auch geben. Auserdem steht im Vordergrund Sachen wie z.B. booten aus dem SRAM, In-Application-Programming, FPU, Core-Coupled-RAM usw. Mal sehn wie weit ich komme ;)&lt;br /&gt;
&lt;br /&gt;
==Die Entwicklungsumgebung==&lt;br /&gt;
===Hardware===&lt;br /&gt;
Zum testen der Anwendungen, benutze ich das STM32F4-Discovery Board, welches einen Debugger, Peripherie und natürlich einen STM32 Controller (STM32F407VGT6) enthält. Deshalb sind alle Beispiele hier für den STM32F407VG Controller ausgelegt, können aber meisten 1:1 auf andere Controller portiert werden. Ich werde auch möglichsts keine STM32F4-Discovery Board spezifischen Libraries verwenden, damit der Portierungs-Vorgang möglichsts einfach bleibt.&lt;br /&gt;
&lt;br /&gt;
===Software===&lt;br /&gt;
In diesem Tutorial verwende ich [http://www.emblocks.org/ Em::Blocks] als IDE. Em::Blocks ist eine kostenlose, uneingeschränkte IDE, die alle STM32 Mikrcontroller unterstützt und sehr einfach zu bedienen ist.&lt;br /&gt;
nach dem Download kann die IDE per Dialog, sehr einfach, installiert werden. Als Compiler beinhaltet Em::Blocks den &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
Die IDE unterstützt zurzeit den ST-Link, den J-Link und es gibt eine Generic-Vorlage, durch welche andere Debugger konfiguriert werden können.&lt;br /&gt;
&lt;br /&gt;
Außerdem muss noch der passende Treiber für den Debugger installiert werden. Verwendet man ein Discovery-Board muss der [http://www.st.com/web/catalog/tools/FM146/CL1984/SC724/SS1677/PF251168 ST-Link/V2]-Treiber heruntergeladen und installiert werden. (Die Installation muss evtl. als Administrator ausgeführt werden, da sonst die Installation unvollständig wird.) Nach der Installation des Treibers kann man den Debugger über die entsprechende USB Schnittstelle an den PC anschließen und es sollte die Meldung von Windows kommen, dass der richtige Treiber gefunden wurde.&lt;br /&gt;
&lt;br /&gt;
===Libraries===&lt;br /&gt;
Zum programmieren benötigt man noch die [http://www.arm.com/products/processors/cortex-m/cortex-microcontroller-software-interface-standard.php CMSIS] und die Standard-Peripheral-Library (z.B. für die F4 Controller [http://www.st.com/stonline/stappl/productcatalog/app?page=partNumberSearchPage&amp;amp;levelid=SS1577&amp;amp;parentid=1743&amp;amp;resourcetype=SW Standard-Peripheral-Library-F4]), die man am besten in einen Ordner (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\STM32&#039;&#039;&#039;&#039;&#039;) entpackt&lt;br /&gt;
&lt;br /&gt;
==Basis-Wissen zur IDE==&lt;br /&gt;
Einige Grundfunktionalitäten der IDE:&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von Dateien zum Projekt===&lt;br /&gt;
Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf &amp;lt;ProjektName&amp;gt; -&amp;gt; Add files...&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Enfernen von Dateien aus dem Projekt===&lt;br /&gt;
Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf die Datei / mehrere Dateien auswählen -&amp;gt; Remove file from project&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
Die Dateien werden lediglich aus dem Projekt entfernt und nicht von der Festplatte gelöscht.&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von Include-Pfaden===&lt;br /&gt;
Sofern die Include-Datei(en) nicht im standard Include-Ordner &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; des Projektes liegen, muss man den Pfad zum Projekt hinzufügen, damit der Compiler die Include-Dateien später auch finden kann. Man geht wie folgt vor: Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf &amp;lt;ProjektName&amp;gt; -&amp;gt; Build options... -&amp;gt; Search Directories -&amp;gt; Add&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Compilieren===&lt;br /&gt;
Entweder über das &#039;&#039;&#039;&#039;&#039;Build&#039;&#039;&#039;&#039;&#039; Menü oder über &#039;&#039;&#039;&#039;&#039;F7&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Um eine genau Ausgabe des Compiler-Aufrufes mit allen Argumenten zu bekommen, geht man im &#039;&#039;&#039;&#039;&#039;Settings&#039;&#039;&#039;&#039;&#039; Menü auf &#039;&#039;&#039;&#039;&#039;Tools...&#039;&#039;&#039;&#039;&#039; und dann auf &#039;&#039;&#039;&#039;&#039;Toolchain executables&#039;&#039;&#039;&#039;&#039;. Ganz unten, unter &#039;&#039;&#039;&#039;&#039;Logging&#039;&#039;&#039;&#039;&#039; kann man dann &#039;&#039;&#039;&#039;&#039;Full command line&#039;&#039;&#039;&#039;&#039; auswählen.&lt;br /&gt;
&lt;br /&gt;
===Debuggen===&lt;br /&gt;
*Als erstes den Debugger starten über das &#039;&#039;&#039;&#039;&#039;Debug&#039;&#039;&#039;&#039;&#039; Menü und &#039;&#039;&#039;&#039;&#039;Start/stop Debug Session&#039;&#039;&#039;&#039;&#039; oder über &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
*Danach läuft die Anwendung auf dem Controller und warten im &#039;&#039;&#039;&#039;&#039;Reset_Handler&#039;&#039;&#039;&#039;&#039; auf Einzelschritt- bzw. Run- Befehle (&#039;&#039;&#039;&#039;&#039;F5, F10, F11&#039;&#039;&#039;&#039;&#039; usw..(siehe &#039;&#039;&#039;&#039;&#039;Debug-Menü&#039;&#039;&#039;&#039;&#039; für alle Möglichkeiten))&lt;br /&gt;
&lt;br /&gt;
*Mit &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039; wird die Debug-Session auch wieder beendet&lt;br /&gt;
&lt;br /&gt;
*Unter &#039;&#039;&#039;&#039;&#039;Debug -&amp;gt; Interfaces -&amp;gt; Target settings&#039;&#039;&#039;&#039;&#039; können Eigenschaften, wie z.B &#039;&#039;&#039;&#039;&#039;Run to main()&#039;&#039;&#039;&#039;&#039; aktiviert werden.&lt;br /&gt;
&lt;br /&gt;
===Projekt als Template abspeichern===&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;File -&amp;gt; Save project as template...&#039;&#039;&#039;&#039;&#039;. Das Template erscheint dann im Projekt-Dialog unter &#039;&#039;&#039;&#039;&#039;User templates&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Das erste Projekt erstellen==&lt;br /&gt;
Hier erkläre ich, wie man am Besten (aus meiner Sicht), ein neues Projekt von Grund auf erstellt, sodass man hinterher, den Controller-Kern über die CMSIS-Library und die Peripherie über die Register steuern kann.&lt;br /&gt;
&lt;br /&gt;
===1. Projekt mit der IDE erstellen===&lt;br /&gt;
Nach der Installation der oben beschriebenen Komponenten erstellt man am besten ein Verzeichnis (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\EmBlocks&#039;&#039;&#039;&#039;&#039;), indem später alle Projekte gespeichert werden. Für Libraries kann man auch noch ein Verzeichnis (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\STM32&#039;&#039;&#039;&#039;&#039;) erstellen, wo alle Libraries gespeichert werden, die man für die Projekt brauchen.&lt;br /&gt;
&lt;br /&gt;
Als nächstes starten man EmBlocks. Bei dem ersten Start öffnet sich ein Fenster, wo verschiedene Compiler angezeigt werden, die Em::Blocks findet. Dort wählt man den &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039; aus und klickt &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039;. Nun sollte sich das Hauptfenster von Em::Blocks öffnen. Über &#039;&#039;&#039;&#039;&#039;Create a new Project&#039;&#039;&#039;&#039;&#039; oder &#039;&#039;&#039;&#039;&#039;File -&amp;gt; New -&amp;gt; Project&#039;&#039;&#039;&#039;&#039; ruft man den Projekt-Dialog auf und kann ein neues Projekt erzeugen.&lt;br /&gt;
&lt;br /&gt;
Auf der Ersten Seite wählen man den &#039;&#039;&#039;&#039;&#039;STmicro-ARM&#039;&#039;&#039;&#039;&#039; Projekt-Typ aus.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_1.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auf der nächsten Seite wird man darauf hingewiesen, dass das der entsprechende Projekt-Typ-Dialog ausgeführt wird. Hier kann man ein Häkchen bei &#039;&#039;&#039;&#039;&#039;Skip this page next time&#039;&#039;&#039;&#039;&#039; setzen und auf &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; klicken.&lt;br /&gt;
&lt;br /&gt;
Im nächsten Schritt wählen man das zuvor erstellt Verzeichnis unter &#039;&#039;&#039;&#039;&#039;Folder to create Project in&#039;&#039;&#039;&#039;&#039; aus, indem später alle Projekt gespeichert werden. Außerdem geben wir dem Projekt einen Namen (z.B. &#039;&#039;&#039;&#039;&#039;FirstProject&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_2.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danach muss man einen Compiler auswählen und bestimmen, welche Projekt-Konfigurationen erszeugt werden sollen. Unter &#039;&#039;&#039;&#039;&#039;Compiler&#039;&#039;&#039;&#039;&#039; wählt man &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039; und man kann das Häkchen bei &#039;&#039;&#039;&#039;&#039;Create &amp;quot;Release&amp;quot; configuration&#039;&#039;&#039;&#039;&#039; entfernen, da diese unnötig ist, die Debug-Konfiguration sollte eig. immer ausreichen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_3.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auf den folgenden Seite wird der Controller ausgewählt. Verwendet man ein STM32F4-Discovery Board müssen folgende Dinge gewählt werden: &#039;&#039;&#039;&#039;&#039;Cortex_M4 (F3xx - F4xx) -&amp;gt; STM32F4xx (Cortex M4 with FPU) -&amp;gt; STM32F407VG&#039;&#039;&#039;&#039;&#039;. Leider sind die Auswahl Möglichkeiten nicht ganz richtig, da auch die F3 Controller einen Cortex M4 Kern und eine FPU haben (Ist aber nicht so wichtig, ist nur eine formale Sache). Außerdem entfernt man das Häkchen bei &#039;&#039;&#039;&#039;&#039;Standard Peripherals Library&#039;&#039;&#039;&#039;&#039; (Wie man die Standard-Peripheral-Library einbindet und verwendet erkläre ich später). Man kann auch das Häkchen bei &#039;&#039;&#039;&#039;&#039;Create hex file for Realease target&#039;&#039;&#039;&#039;&#039; entfernen.&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;Stack Size&#039;&#039;&#039;&#039;&#039; und &#039;&#039;&#039;&#039;&#039;Heap Size&#039;&#039;&#039;&#039;&#039; wird die Größe von Stack und Heap festgelegt. Für eine erste Anwendung kann man die Einstellungen so lassen (Stack-Size: 0x0100 =&amp;gt; 256 Byte Stack und Heap-Size: 0x0000 =&amp;gt; kein Heap). Mit &#039;&#039;&#039;&#039;&#039;Finish&#039;&#039;&#039;&#039;&#039; ist der Projekt Dialog abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_4.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danach sollten sich zwei neue Fenster öffnen, um die Debug-Eigenschaften fest zu legen.&lt;br /&gt;
Verwendet man ein Discovery Board/ST-Link müssen die Einstellungen wie auf dem Bild gewählt werden. Über den Button &#039;&#039;&#039;&#039;&#039;Settings&#039;&#039;&#039;&#039;&#039; öffnet sich das zweite Fenster, falls sich dieses nicht schon von alleine öffnen sollte. Nach den Schließen der Fenster über &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; ist der Projekt Dialog beendet und ein neues Projekt steht zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_5_1.png|Debug Eigenschaften 1. Fenster]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_5_2.png|Debug Eigenschaften 2. Fenster]]&lt;br /&gt;
&lt;br /&gt;
===2. CMSIS-Library und Startup-Code hinzufügen===&lt;br /&gt;
Wenn man sich, nachdem man ein neues Projekt in der IDE erstellt hat, die bereits vorhandenen Dateien im Projekt ansieht, stellt man fest, das bereits ein Ordner &#039;&#039;&#039;&#039;&#039;cmsis&#039;&#039;&#039;&#039;&#039; existiert, der einige wichtige Include-Dateien der CMSIS-Library enthält. Allerdings sind das wirklich nur die wichtigsten Include-Dateien der CMSIS-Library und dazu noch, die aus einer älternen Version. Ich ziehe es deshalb vor die &amp;quot;Mini-CMSIS-Libraray&amp;quot; und die &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c/.h&#039;&#039;&#039;&#039;&#039; Dateien des Projektes durch aktuellere Versionen zu ersetzen. So ist später auch die Integration  von anderen Libraries, wie z.B. der CMSIS-DSP-Libarary einfacher.  &lt;br /&gt;
&lt;br /&gt;
Zunächst gehen man in das Projekt-Verzeichnis und löscht:&lt;br /&gt;
*Den Ordner &#039;&#039;&#039;&#039;&#039;cmsis&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Alle Dateien im Include Verzeichnis &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; im &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner&lt;br /&gt;
&lt;br /&gt;
Außerdem entfernt man auch alle gelöschten Dateien in der IDE aus dem Projekt mit &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Rechts Klick -&amp;gt; Remove file from project&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Es sollte folgende Verzeichnis Struktur überbleiben:&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_6.png|Überbleibende Dateien]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Jetzt müssen die gelöschten Dateien durch die aktuelleren ersetzt werden.&lt;br /&gt;
&lt;br /&gt;
*Dazu kopieren man den gesamten Ordner &#039;&#039;&#039;&#039;&#039;CMSIS&#039;&#039;&#039;&#039;&#039; aus dem CMSIS Download in das Projekt Verzeichnis.&lt;br /&gt;
&lt;br /&gt;
*Aus dem Standard-Peripheral-Library Download kopiert man von &#039;&#039;&#039;&#039;&#039;Libraries\CMSIS\Device\ST\STM32F4xx\Include&#039;&#039;&#039;&#039;&#039; alle Dateien in den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projekt Verzeichnisses&lt;br /&gt;
&lt;br /&gt;
*Aus der Standard-Peripheral-Library kopieren man ebenfalls von &#039;&#039;&#039;&#039;&#039;Libraries\CMSIS\Device\ST\STM32F4xx\Source\Templates&#039;&#039;&#039;&#039;&#039; die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; in den &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner des Projekts&lt;br /&gt;
&lt;br /&gt;
Anschließend müssen die neuen Dateien in der IDE dem Projekt hinzugefügt werden. Dazu benutzt man &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Rechts Klick -&amp;gt; Add files&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
*Aus dem &#039;&#039;&#039;&#039;&#039;CMSIS&#039;&#039;&#039;&#039;&#039; Ordner im Projekt Verzeichnis werden aus den Unterorder &#039;&#039;&#039;&#039;&#039;Include&#039;&#039;&#039;&#039;&#039; folgende Dateien dem Projekt hinzugefügt:&lt;br /&gt;
**arm_common_tables.h&lt;br /&gt;
**arm_const_structs.h&lt;br /&gt;
**arm_math.h&lt;br /&gt;
**core_cm4.h&lt;br /&gt;
**core_cm4_simd.h&lt;br /&gt;
**core_cmFunc.h&lt;br /&gt;
**core_cmInstr.h&lt;br /&gt;
*Alle Dateien aus den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projektes&lt;br /&gt;
*Die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; aus dem &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner&lt;br /&gt;
&lt;br /&gt;
So sollte die Struktur dann aussehen:&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_7.png|Anwenungs-Grundgerüst]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Da einige Dateien der Libraries später bearbeitet werden müssen und Schreibgeschützt sind, weise ich hier schonmal darauf hin, das der Schreibschutz in der IDE über &#039;&#039;&#039;&#039;&#039;Rechts Klick auf die Datei -&amp;gt; Properties -&amp;gt; Häkchen bei &amp;quot;File is read only&amp;quot; entfernen&#039;&#039;&#039;&#039;&#039; entfert werden kann.&lt;br /&gt;
&lt;br /&gt;
Damit die IDE die Header-Dateien der CMSIS Library auch finden kann, weil diese ja nicht im standard Include Ordner &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; liegen, muss unter &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Build Options -&amp;gt; Search Directories&#039;&#039;&#039;&#039;&#039; der Pfad &#039;&#039;&#039;&#039;&#039;CMSIS\Include&#039;&#039;&#039;&#039;&#039; hinzugefügt werden.&lt;br /&gt;
&lt;br /&gt;
Compiliert man jetzt das Projekt mit &#039;&#039;&#039;&#039;&#039;F7&#039;&#039;&#039;&#039;&#039; gibt es ein paar Fehler Meldungen, weil keine Controller-Reihe ausgewählt wurde. Ebenfalls unter &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Build Options -&amp;gt; Compiler Settings -&amp;gt; #defines&#039;&#039;&#039;&#039;&#039; wird der Define &#039;&#039;&#039;&#039;&#039;STM32F40_41xxx&#039;&#039;&#039;&#039;&#039; hinzugefügt.&lt;br /&gt;
&lt;br /&gt;
Beim erneuten Compilieren sollten sich nun keine neuen Fehler ergeben.&lt;br /&gt;
&lt;br /&gt;
===Das erste Programm===&lt;br /&gt;
Nachdem ein grundsätzliches &amp;quot;Gerüst&amp;quot; fertig ist, kann man den ersten Code schreiben.&lt;br /&gt;
main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC-&amp;gt;AHB1ENR |= RCC_AHB1ENR_GPIODEN;    //Takt für GPIO aktivieren&lt;br /&gt;
    GPIOD-&amp;gt;MODER |= GPIO_MODER_MODER15_0;   //GPIOD Pin15 als Ausgang&lt;br /&gt;
    GPIOD-&amp;gt;BSRRL |= GPIO_BSRR_BS_15;        //GPIOD Pin15 auf High ziehen&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039; wird dann der Debugger gestartet. Hat der Debugger das Projekt erfolgreich übertragen kann die Ausführung mit &#039;&#039;&#039;&#039;&#039;F5&#039;&#039;&#039;&#039;&#039; begonnen werden.&lt;br /&gt;
&lt;br /&gt;
==Libraries einbinden/verwenden==&lt;br /&gt;
===Einbinden der Standard-Peripheral-Library===&lt;br /&gt;
Um nicht immer die einzelnen Register, wie im ersten &amp;quot;bare-metal&amp;quot; Beispiel, aus dem Reference-Manual zu suchen und zu beschreiben, gibt es von ST die Standard Peripheral Library, die diese Aufgaben übernimmt und mit der sich die &amp;quot;normale/grundlegende&amp;quot; (Alles außer USB und Ethernet) Peripherie recht einfach steuern lässt. Um die Library zu verwenden erzeugt man wie oben beschrieben ein neues Grundgerüst und kopiert als erstes den Ordner &#039;&#039;&#039;&#039;&#039;Libraries\STM32F4xx_StdPeriph_Driver&#039;&#039;&#039;&#039;&#039; aus dem Standard-Peripheral-Library Download in das Projekt-Verzeichnis. Außerdem muss man die Datei &#039;&#039;&#039;&#039;&#039;Project\STM32F4xx_StdPeriph_Templates\stm32f4xx_conf.h&#039;&#039;&#039;&#039;&#039; ebenfalls aus dem Standard-Peripheral-Library Download in den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projektes kopieren. In der IDE fügt man den Include-Path &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\inc&#039;&#039;&#039;&#039;&#039; hinzufügen, wie bei der CMSIS-Library (s.o.).&lt;br /&gt;
Außerdem muss noch &#039;&#039;&#039;&#039;&#039;USE_STDPERIPH_DRIVER&#039;&#039;&#039;&#039;&#039; als Define in der IDE hinzugefügt werden (s.o.).&lt;br /&gt;
Danach fügt man die Source- und Include-Dateien aus dem Ordner &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\inc&#039;&#039;&#039;&#039;&#039; und &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\src&#039;&#039;&#039;&#039;&#039; dem Project mit &#039;&#039;&#039;&#039;&#039;&amp;lt;Project Name&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Add files&#039;&#039;&#039;&#039;&#039; hinzu, allerdings nur die, für welche auch der Controller die entsprechende Peripherie besitzt. Beim STM32F4-Discovery Board / STM32F407VG Controller dürfen also nicht folgende Dateien nicht mit hinzugefügt werden, weil diese Peripherie nur bei anderen Controller vorhanden ist:&lt;br /&gt;
&lt;br /&gt;
*stm32f4xx_dma2d.c/.h&lt;br /&gt;
*stm32f4xx_fmc.c/.h&lt;br /&gt;
*stm32f4xx_ltdc.c/.h&lt;br /&gt;
*stm32f4xx_sai.c/.h&lt;br /&gt;
&lt;br /&gt;
Daraus resultiert folgende Struktur:&lt;br /&gt;
&lt;br /&gt;
[[Datei:stdperiphlib_2.png|Header-Struktur]] [[Datei:stdperiphlib_1.png|Source-Struktur]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Anschließen kann die Standard-Peripheral-Library benutz werden.&lt;br /&gt;
main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);&lt;br /&gt;
&lt;br /&gt;
    GPIO_InitTypeDef GPIOD_InitStructure;&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Mode = GPIO_Mode_OUT;     //Als Ausgang&lt;br /&gt;
    GPIOD_InitStructure.GPIO_OType = GPIO_OType_PP;    //Push-Pull Betrieb&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Pin = GPIO_Pin_15;        //Pin 15 (STM32F4-Discovery: Blaue LED)&lt;br /&gt;
    GPIOD_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;  //Kein Pull-Up oder Pull-Down Widerstand aktiviert&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Speed = GPIO_Speed_25MHz; //25MHz Update-Rate&lt;br /&gt;
    GPIO_Init(GPIOD, &amp;amp;GPIOD_InitStructure);&lt;br /&gt;
&lt;br /&gt;
    GPIO_SetBits(GPIOD, GPIO_Pin_15);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Startup-Code, Linker-Script, Takt, FPU usw.==&lt;br /&gt;
===Startup-Code===&lt;br /&gt;
Em::Blocks fügt standardmäßig einen Startup-Code mit in das Projekt ein. Die wichtigsten Dinge die darin erledigt werden sind folgende:&lt;br /&gt;
&lt;br /&gt;
*Stack und Heap wird angelgt&lt;br /&gt;
*Die Vector-Table wird angelegt&lt;br /&gt;
*Ein Default Reset-Handler wird implementiert, dieser erledigt folgende aufgaben:&lt;br /&gt;
**Kopieren der definierten Daten aus dem Flash in den SRAM&lt;br /&gt;
**&#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; wird aufgerfen, wenn &#039;&#039;&#039;&#039;&#039;__NO_SYSTEM_INIT&#039;&#039;&#039;&#039;&#039; nicht definiert ist&lt;br /&gt;
**Sprung in die &#039;&#039;&#039;&#039;&#039;main()&#039;&#039;&#039;&#039;&#039; Funktion&lt;br /&gt;
*Allen anderen Interrupt-Handler wird eine Default-Funktion &#039;&#039;&#039;&#039;&#039;def_irq_handler&#039;&#039;&#039;&#039;&#039; mit einer &#039;&#039;&#039;&#039;&#039;while(1)&#039;&#039;&#039;&#039;&#039;-Schleife zugewiesen, falls kein anderer Interrupt-Handler existiert.&lt;br /&gt;
&lt;br /&gt;
Normalerweise muss am Startup-Code nichts verändert werden.&lt;br /&gt;
&lt;br /&gt;
===Linker-Script===&lt;br /&gt;
===Der Takt===&lt;br /&gt;
Jeder Controller oder Prozessor braucht einen Takt, indem er die einzelnen Maschinen-Befehle abarbeiten kann.&lt;br /&gt;
Bei den STM32 Mikrocontrollern kann dieser Takt aus verschiedenen Quellen kommen:&lt;br /&gt;
&lt;br /&gt;
1. High Speed Internal Oszillator (HSI)&lt;br /&gt;
&lt;br /&gt;
2. High Speed External Oszillator (HSE)&lt;br /&gt;
&lt;br /&gt;
3. Low Speed Internal Oszillator (LSI)&lt;br /&gt;
&lt;br /&gt;
4. Low Speed External Oszillator (LSE)&lt;br /&gt;
&lt;br /&gt;
5. Phase-Locked Loop (PLL) (generiert den Takt aus den ersten vier Taktquellen durch Teiler und Faktoren)&lt;br /&gt;
&lt;br /&gt;
Nach einem Reset wird der Controller aus der HSI Taktquelle versorgt (16MHz beim STM32F407VG). Um die voll Performance des Controllers zu erreichen muss die PLL verwendet werden, welche den Takt durch geschickte Teiler und Faktoren vervielfältigt, sodass am Ende der Controller mit der maximalen Taktfrequenz läuft. Die notwendige Initialisierung der PLL findet in der Funktion &#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; statt. Die PLL erzeugt zunächst einen Basistakt:&lt;br /&gt;
&lt;br /&gt;
PLL_VCO = (F_HSE / PLL_M) * PLL_N&lt;br /&gt;
&lt;br /&gt;
Aus diesem Takt wird dann der Takt für den Controller-Kern abgeleitet:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = PLL_VCO / PLL_P&lt;br /&gt;
&lt;br /&gt;
Und der Takt für SDIO / USB / RNG (48MHz):&lt;br /&gt;
&lt;br /&gt;
48MHz = PLL_VCO / PLL_Q&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Durch weiter Teiler werden, die Takte für die einzelnen Busse erzeugt, da diese nicht alle beliebig schnell betrieben werden dürfen.&lt;br /&gt;
&lt;br /&gt;
Genaue Angaben findet man zu dem jeweiligen Clock-System des Controllers im Reference Manual.&lt;br /&gt;
&lt;br /&gt;
Ein Blick in den &amp;quot;Kommentar-Header&amp;quot; verrät, dass von einem externen (HSE) Oszillator von 25MHz ausgegangen wird, der die PLL versorgen soll.&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((25MHz / PLL_M(25)) * PLL_N(336)) / PLL_P(2) = 168MHz&lt;br /&gt;
&lt;br /&gt;
Allerdings stimmt diese Rechnung natürlich nur, wenn wirklich ein 25MHz Quarz am Controller angeschlossen ist. Auf dem STM32F4-Discovery Board befindet sich aber nur ein 8MHz Quarz. Demnach gilt:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((8MHz / PLL_M(25)) * PLL_N(336)) / PLL_P(2) = 53.76MHz&lt;br /&gt;
&lt;br /&gt;
Der Controller läuft also nur mit 53.76MHz, wenn wie ober beschrieben ein Projekt erstellt wird. Allerdings kann dieses Problem durch ändern von den betroffen Defines behoben werden:&lt;br /&gt;
 &lt;br /&gt;
*Dazu geht man in die &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; Datei und passt zur Vollständigkeit erstmal die zum Controller passende Tabelle im &amp;quot;Kommentar-Header&amp;quot; an (Z.57f):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      HSE Frequency(Hz)                      | 8000000&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      PLL_M                                  | 8&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Danach passt man den PPL_M Define (Z.254) an:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/************************* PLL Parameters *************************************/&lt;br /&gt;
/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */&lt;br /&gt;
#define PLL_M      8&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Außerdem muss man den HSE_VALUE Define in der &#039;&#039;&#039;&#039;&#039;inc/stm32f4xx.h&#039;&#039;&#039;&#039;&#039; angepasst werden (Z.122):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#if !defined  (HSE_VALUE)&lt;br /&gt;
  #define HSE_VALUE    ((uint32_t)8000000) /*!&amp;lt; Value of the External oscillator in Hz */&lt;br /&gt;
&lt;br /&gt;
#endif /* HSE_VALUE */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine neue Berechnung zeigt:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((8MHz / PLL_M(8)) * PLL_N(336)) / PLL_P(2) = 168MHz&lt;br /&gt;
&lt;br /&gt;
Jetzt läuft der Controller mit maximaler Geschwindigkeit.&lt;br /&gt;
&lt;br /&gt;
Die Theorie wird durch folgendes Programm verifiziert. Der geviertelte System-Takt SYSCLK wir am Pin PC9 ausgegeben. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);&lt;br /&gt;
&lt;br /&gt;
    GPIO_InitTypeDef GPIOC_InitStructure;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Mode = GPIO_Mode_AF;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_OType = GPIO_OType_PP;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Pin = GPIO_Pin_9;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;&lt;br /&gt;
    GPIO_Init(GPIOC, &amp;amp;GPIOC_InitStructure);&lt;br /&gt;
&lt;br /&gt;
    RCC_MCO2Config(RCC_MCO2Source_SYSCLK, RCC_MCO2Div_4);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Die FPU===&lt;br /&gt;
====Allgemeines====&lt;br /&gt;
Damit die FPU richtig verwendet wird, müssen normalerweise zwei Bedingungen erfüllt sein:&lt;br /&gt;
&lt;br /&gt;
1. Der Controller muss in der Initialisierung-Funktion &#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; in &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; die FPU Hardware-seitig aktivieren&lt;br /&gt;
&lt;br /&gt;
2. Damit die FPU auch was zu tuen bekommt, müssen vom Compiler FPU-Instructions erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
Die Em::Blocks IDE verwendet standardmäßig die FPU, wenn eine Vorhanden ist. Hier wird die FPU Hardware-seitig aktiviert (&#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; Z.341):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* FPU settings ------------------------------------------------------------*/&lt;br /&gt;
  #if (__FPU_PRESENT == 1) &amp;amp;&amp;amp; (__FPU_USED == 1)&lt;br /&gt;
    SCB-&amp;gt;CPACR |= ((3UL &amp;lt;&amp;lt; 10*2)|(3UL &amp;lt;&amp;lt; 11*2));  /* set CP10 and CP11 Full Access */&lt;br /&gt;
  #endif&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
__FPU_PRESENT wird in der &#039;&#039;&#039;&#039;&#039;stm32f4xx.h&#039;&#039;&#039;&#039;&#039; definiert.&lt;br /&gt;
__FPU_USED wird von der IDE übernommen (siehe Build-Log): &#039;&#039;&#039;&#039;&#039;-D__FPU_USED&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Außerdem wird der Compiler von der IDE standardmäßig mit dem Argument &#039;&#039;&#039;&#039;&#039;-mfloat-abi=hard&#039;&#039;&#039;&#039;&#039; aufgerufen, wodurch FPU-Instructions erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
====FPU abschalten====&lt;br /&gt;
Um die FPU ab zu schalten (Mir würde jetzt nur Strom sparen als Grund einfallen) geht man wie folgt vor:&lt;br /&gt;
&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick Build options -&amp;gt; Device -&amp;gt; Policy&#039;&#039;&#039;&#039;&#039; wählt man &#039;&#039;&#039;&#039;&#039;Use target settings&#039;&#039;&#039;&#039;&#039; und über nimmt die Einstellungen, die vorher dort eingetragen waren, allerdings lässt man das Feld &#039;&#039;&#039;&#039;&#039;FP-hardware&#039;&#039;&#039;&#039;&#039; frei.&lt;br /&gt;
&lt;br /&gt;
[[Datei:fpu_1.png|FPU Abschalten Schritt 1]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;Compiler Settings -&amp;gt; Policy&#039;&#039;&#039;&#039;&#039; wählt man dann &#039;&#039;&#039;&#039;&#039;Use target options only&#039;&#039;&#039;&#039;&#039;. Dann kann man unter &#039;&#039;&#039;&#039;&#039;Categories&#039;&#039;&#039;&#039;&#039; die Option &#039;&#039;&#039;&#039;&#039;ARM FPU architecture&#039;&#039;&#039;&#039;&#039; auswählen. Dort stehen dann drei Möglichkeiten für die FPU zur Verfügung:&lt;br /&gt;
&lt;br /&gt;
1. Software-FPU-Library für Gleitkomma-Berechnung verwenden - Keine FPU-Instructions werden generiert (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=soft&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
2. Eine Mischung aus Software- und Hardware-FPU wird verwendet (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=softfp&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
3. Hardware-FPU wird für Gleitkomma-Berechnungen verwendet (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=hard&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
[[Datei:fpu_2.png|FPU Abschalten Schritt 2]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Um die FPU ab zu schalten wählt man natürlich die erste Möglichkeit.&lt;br /&gt;
Bei der 2. und 3. Möglichkeit fügt die IDE auch den Define &#039;&#039;&#039;&#039;&#039;__FPU_USED&#039;&#039;&#039;&#039;&#039; hinzu. Bei Der ersten Möglichkeit nicht. Der Code muss also nicht verändert / auskommentiert werden.&lt;br /&gt;
&lt;br /&gt;
Um die FPU wieder zu aktivieren müssen alle Schritte wieder rückgängig gemacht werden.&lt;br /&gt;
&lt;br /&gt;
Am besten ist es einfach mal alle Möglichkeiten im Einzelschritt durch zu probieren. Dann stellt man schnell fest, ob die FPU aktiviert wir oder nicht. Ein Blick in den erweiterten &#039;&#039;&#039;&#039;&#039;Build-Log&#039;&#039;&#039;&#039;&#039; gibt auch schnell Aufschluss darüber, wie der Compiler aufgerufen wird (siehe Kapitel [http://www.mikrocontroller.net/articles/STM32_-_Einstieg_mit_Em::Blocks#Compilieren Compilieren]).&lt;br /&gt;
&lt;br /&gt;
====Test Programm für die FPU====&lt;br /&gt;
Hier ein kleines Testprogramm, dass misst wie viele Taktzyklen für eine Gleitkomma-Multiplikation gebraucht werden. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define CORE_SysTickEn()    (*((u32*)0xE0001000)) = 0x40000001&lt;br /&gt;
#define CORE_SysTickDis()   (*((u32*)0xE0001000)) = 0x40000000&lt;br /&gt;
#define CORE_GetSysTick()   (*((u32*)0xE0001004))&lt;br /&gt;
&lt;br /&gt;
uint32_t t1, t2, dt;&lt;br /&gt;
float x, y, z;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    x = 53.64f;&lt;br /&gt;
    y = 0.27f;&lt;br /&gt;
&lt;br /&gt;
    CORE_SysTickEn();&lt;br /&gt;
    t1 = CORE_GetSysTick();&lt;br /&gt;
&lt;br /&gt;
    z = x * y;&lt;br /&gt;
&lt;br /&gt;
    t2 = CORE_GetSysTick();&lt;br /&gt;
    CORE_SysTickDis();&lt;br /&gt;
&lt;br /&gt;
    dt = t2 - t1;&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mein Ergebnis:&lt;br /&gt;
*Mit Hardware-FPU:  dt = 25&lt;br /&gt;
*Ohne Hardware-FPU: dt = 83&lt;br /&gt;
&lt;br /&gt;
==Booten aus dem SRAM==&lt;br /&gt;
STM32 Controller haben die Möglichkeit Code aus dem Flash als auch aus dem SRAM auszuführen. Um eine Anwenung per Debugger in des SRAM zu laden sind nur wenige Schritte erforderlich:&lt;br /&gt;
&lt;br /&gt;
*Um das Linkerscript für den SRAM zu verwenden geht man zu: &#039;&#039;&#039;&#039;&#039;Build options... -&amp;gt; Device&#039;&#039;&#039;&#039;&#039; dort wählt man unter &#039;&#039;&#039;&#039;&#039;Policy&#039;&#039;&#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;Use target settings&#039;&#039;&#039;&#039;&#039; aus und übernimmt die vorherigen Einstellungen, nur unter &#039;&#039;&#039;&#039;&#039;Linker script*&#039;&#039;&#039;&#039;&#039; gibt man &#039;&#039;&#039;&#039;&#039;.\stm32f407vg_sram.ld&#039;&#039;&#039;&#039;&#039; an&lt;br /&gt;
&lt;br /&gt;
*Dann muss man noch unter &#039;&#039;&#039;&#039;&#039;Debug -&amp;gt; Interfaces -&amp;gt; Settings&#039;&#039;&#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;Vector table start&#039;&#039;&#039;&#039;&#039; auf 0x20000000 ändern und &#039;&#039;&#039;&#039;&#039;Execute from RAM&#039;&#039;&#039;&#039;&#039; auswählen.&lt;br /&gt;
&lt;br /&gt;
Anschließend kann man die Anwendung ganz normal debuggen. Nach einem Reset muss die Anwenung erneut mit dem Debugger gestartet werden.&lt;br /&gt;
&lt;br /&gt;
=Fortsetzung folgt..=&lt;br /&gt;
Kritik, Wünsche usw. sind gerne erwünscht, am besten hier in den Thread posten: [http://www.mikrocontroller.net/topic/323750 Neues STM32 Tutorial]&lt;br /&gt;
&lt;br /&gt;
[[Category:ARM]]&lt;br /&gt;
[[Category:STM32]]&lt;/div&gt;</summary>
		<author><name>Avrprogger</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=STM32_-_Einstieg_mit_Em::Blocks&amp;diff=81511</id>
		<title>STM32 - Einstieg mit Em::Blocks</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=STM32_-_Einstieg_mit_Em::Blocks&amp;diff=81511"/>
		<updated>2014-02-10T16:28:38Z</updated>

		<summary type="html">&lt;p&gt;Avrprogger: fdg&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In diesem Tutorial werde ich versuchen, möglichst einfach, die ersten Schritte zur Entwicklung von STM32 Anwenungen mit der Em::Blocks IDE zu erklären. Hier soll nicht so stark auf die einzelnen Peripherie-Module der Controller eingegangen werden, sondern mehr auf die IDE und die verschieden Libraries, wie die CMSIS Library, die DSP-Library, die Standard-Peripheral-Library, die USB-Library und vllt. über Ethernet. Ich denke ein Kapitel zu FreeRTOS wird es auch geben. Auserdem steht im Vordergrund Sachen wie z.B. booten aus dem SRAM, In-Application-Programming, FPU, Core-Coupled-RAM usw. Mal sehn wie weit ich komme ;)&lt;br /&gt;
&lt;br /&gt;
==Die Entwicklungsumgebung==&lt;br /&gt;
===Hardware===&lt;br /&gt;
Zum testen der Anwendungen, benutze ich das STM32F4-Discovery Board, welches einen Debugger, Peripherie und natürlich einen STM32 Controller (STM32F407VGT6) enthält. Deshalb sind alle Beispiele hier für den STM32F407VG Controller ausgelegt, können aber meisten 1:1 auf andere Controller portiert werden. Ich werde auch möglichsts keine STM32F4-Discovery Board spezifischen Libraries verwenden, damit der Portierungs-Vorgang möglichsts einfach bleibt.&lt;br /&gt;
&lt;br /&gt;
===Software===&lt;br /&gt;
In diesem Tutorial verwende ich [http://www.emblocks.org/ Em::Blocks] als IDE. Em::Blocks ist eine kostenlose, uneingeschränkte IDE, die alle STM32 Mikrcontroller unterstützt und sehr einfach zu bedienen ist.&lt;br /&gt;
nach dem Download kann die IDE per Dialog, sehr einfach, installiert werden. Als Compiler beinhaltet Em::Blocks den &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
Die IDE unterstützt zurzeit den ST-Link, den J-Link und es gibt eine Generic-Vorlage, durch welche andere Debugger konfiguriert werden können.&lt;br /&gt;
&lt;br /&gt;
Außerdem muss noch der passende Treiber für den Debugger installiert werden. Verwendet man ein Discovery-Board muss der [http://www.st.com/web/catalog/tools/FM146/CL1984/SC724/SS1677/PF251168 ST-Link/V2]-Treiber heruntergeladen und installiert werden. (Die Installation muss evtl. als Administrator ausgeführt werden, da sonst die Installation unvollständig wird.) Nach der Installation des Treibers kann man den Debugger über die entsprechende USB Schnittstelle an den PC anschließen und es sollte die Meldung von Windows kommen, dass der richtige Treiber gefunden wurde.&lt;br /&gt;
&lt;br /&gt;
===Libraries===&lt;br /&gt;
Zum programmieren benötigt man noch die [http://www.arm.com/products/processors/cortex-m/cortex-microcontroller-software-interface-standard.php CMSIS] und die Standard-Peripheral-Library (z.B. für die F4 Controller [http://www.st.com/stonline/stappl/productcatalog/app?page=partNumberSearchPage&amp;amp;levelid=SS1577&amp;amp;parentid=1743&amp;amp;resourcetype=SW Standard-Peripheral-Library-F4]), die man am besten in einen Ordner (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\STM32&#039;&#039;&#039;&#039;&#039;) entpackt&lt;br /&gt;
&lt;br /&gt;
==Basis-Wissen zur IDE==&lt;br /&gt;
Einige Grundfunktionalitäten der IDE:&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von Dateien zum Projekt===&lt;br /&gt;
Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf &amp;lt;ProjektName&amp;gt; -&amp;gt; Add files...&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Enfernen von Dateien aus dem Projekt===&lt;br /&gt;
Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf die Datei / mehrere Dateien auswählen -&amp;gt; Remove file from project&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
Die Dateien werden lediglich aus dem Projekt entfernt und nicht von der Festplatte gelöscht.&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von Include-Pfaden===&lt;br /&gt;
Sofern die Include-Datei(en) nicht im standard Include-Ordner &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; des Projektes liegen, muss man den Pfad zum Projekt hinzufügen, damit der Compiler die Include-Dateien später auch finden kann. Man geht wie folgt vor: Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf &amp;lt;ProjektName&amp;gt; -&amp;gt; Build options... -&amp;gt; Search Directories -&amp;gt; Add&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Compilieren===&lt;br /&gt;
Entweder über das &#039;&#039;&#039;&#039;&#039;Build&#039;&#039;&#039;&#039;&#039; Menü oder über &#039;&#039;&#039;&#039;&#039;F7&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Um eine genau Ausgabe des Compiler-Aufrufes mit allen Argumenten zu bekommen, geht man im &#039;&#039;&#039;&#039;&#039;Settings&#039;&#039;&#039;&#039;&#039; Menü auf &#039;&#039;&#039;&#039;&#039;Tools...&#039;&#039;&#039;&#039;&#039; und dann auf &#039;&#039;&#039;&#039;&#039;Toolchain executables&#039;&#039;&#039;&#039;&#039;. Ganz unten, unter &#039;&#039;&#039;&#039;&#039;Logging&#039;&#039;&#039;&#039;&#039; kann man dann &#039;&#039;&#039;&#039;&#039;Full command line&#039;&#039;&#039;&#039;&#039; auswählen.&lt;br /&gt;
&lt;br /&gt;
===Debuggen===&lt;br /&gt;
*Als erstes den Debugger starten über das &#039;&#039;&#039;&#039;&#039;Debug&#039;&#039;&#039;&#039;&#039; Menü und &#039;&#039;&#039;&#039;&#039;Start/stop Debug Session&#039;&#039;&#039;&#039;&#039; oder über &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
*Danach läuft die Anwendung auf dem Controller und warten im &#039;&#039;&#039;&#039;&#039;Reset_Handler&#039;&#039;&#039;&#039;&#039; auf Einzelschritt- bzw. Run- Befehle (&#039;&#039;&#039;&#039;&#039;F5, F10, F11&#039;&#039;&#039;&#039;&#039; usw..(siehe &#039;&#039;&#039;&#039;&#039;Debug-Menü&#039;&#039;&#039;&#039;&#039; für alle Möglichkeiten))&lt;br /&gt;
&lt;br /&gt;
*Mit &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039; wird die Debug-Session auch wieder beendet&lt;br /&gt;
&lt;br /&gt;
*Unter &#039;&#039;&#039;&#039;&#039;Debug -&amp;gt; Interfaces -&amp;gt; Target settings&#039;&#039;&#039;&#039;&#039; können Eigenschaften, wie z.B &#039;&#039;&#039;&#039;&#039;Run to main()&#039;&#039;&#039;&#039;&#039; aktiviert werden.&lt;br /&gt;
&lt;br /&gt;
===Projekt als Template abspeichern===&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;File -&amp;gt; Save project as template...&#039;&#039;&#039;&#039;&#039;. Das Template erscheint dann im Projekt-Dialog unter &#039;&#039;&#039;&#039;&#039;User templates&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Das erste Projekt erstellen==&lt;br /&gt;
Hier erkläre ich, wie man am Besten (aus meiner Sicht), ein neues Projekt von Grund auf erstellt, sodass man hinterher, den Controller-Kern über die CMSIS-Library und die Peripherie über die Register steuern kann.&lt;br /&gt;
&lt;br /&gt;
===1. Projekt mit der IDE erstellen===&lt;br /&gt;
Nach der Installation der oben beschriebenen Komponenten erstellt man am besten ein Verzeichnis (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\EmBlocks&#039;&#039;&#039;&#039;&#039;), indem später alle Projekte gespeichert werden. Für Libraries kann man auch noch ein Verzeichnis (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\STM32&#039;&#039;&#039;&#039;&#039;) erstellen, wo alle Libraries gespeichert werden, die man für die Projekt brauchen.&lt;br /&gt;
&lt;br /&gt;
Als nächstes starten man EmBlocks. Bei dem ersten Start öffnet sich ein Fenster, wo verschiedene Compiler angezeigt werden, die Em::Blocks findet. Dort wählt man den &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039; aus und klickt &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039;. Nun sollte sich das Hauptfenster von Em::Blocks öffnen. Über &#039;&#039;&#039;&#039;&#039;Create a new Project&#039;&#039;&#039;&#039;&#039; oder &#039;&#039;&#039;&#039;&#039;File -&amp;gt; New -&amp;gt; Project&#039;&#039;&#039;&#039;&#039; ruft man den Projekt-Dialog auf und kann ein neues Projekt erzeugen.&lt;br /&gt;
&lt;br /&gt;
Auf der Ersten Seite wählen man den &#039;&#039;&#039;&#039;&#039;STmicro-ARM&#039;&#039;&#039;&#039;&#039; Projekt-Typ aus.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_1.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auf der nächsten Seite wird man darauf hingewiesen, dass das der entsprechende Projekt-Typ-Dialog ausgeführt wird. Hier kann man ein Häkchen bei &#039;&#039;&#039;&#039;&#039;Skip this page next time&#039;&#039;&#039;&#039;&#039; setzen und auf &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; klicken.&lt;br /&gt;
&lt;br /&gt;
Im nächsten Schritt wählen man das zuvor erstellt Verzeichnis unter &#039;&#039;&#039;&#039;&#039;Folder to create Project in&#039;&#039;&#039;&#039;&#039; aus, indem später alle Projekt gespeichert werden. Außerdem geben wir dem Projekt einen Namen (z.B. &#039;&#039;&#039;&#039;&#039;FirstProject&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_2.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danach muss man einen Compiler auswählen und bestimmen, welche Projekt-Konfigurationen erszeugt werden sollen. Unter &#039;&#039;&#039;&#039;&#039;Compiler&#039;&#039;&#039;&#039;&#039; wählt man &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039; und man kann das Häkchen bei &#039;&#039;&#039;&#039;&#039;Create &amp;quot;Release&amp;quot; configuration&#039;&#039;&#039;&#039;&#039; entfernen, da diese unnötig ist, die Debug-Konfiguration sollte eig. immer ausreichen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_3.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auf den folgenden Seite wird der Controller ausgewählt. Verwendet man ein STM32F4-Discovery Board müssen folgende Dinge gewählt werden: &#039;&#039;&#039;&#039;&#039;Cortex_M4 (F3xx - F4xx) -&amp;gt; STM32F4xx (Cortex M4 with FPU) -&amp;gt; STM32F407VG&#039;&#039;&#039;&#039;&#039;. Leider sind die Auswahl Möglichkeiten nicht ganz richtig, da auch die F3 Controller einen Cortex M4 Kern und eine FPU haben (Ist aber nicht so wichtig, ist nur eine formale Sache). Außerdem entfernt man das Häkchen bei &#039;&#039;&#039;&#039;&#039;Standard Peripherals Library&#039;&#039;&#039;&#039;&#039; (Wie man die Standard-Peripheral-Library einbindet und verwendet erkläre ich später). Man kann auch das Häkchen bei &#039;&#039;&#039;&#039;&#039;Create hex file for Realease target&#039;&#039;&#039;&#039;&#039; entfernen.&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;Stack Size&#039;&#039;&#039;&#039;&#039; und &#039;&#039;&#039;&#039;&#039;Heap Size&#039;&#039;&#039;&#039;&#039; wird die Größe von Stack und Heap festgelegt. Für eine erste Anwendung kann man die Einstellungen so lassen (Stack-Size: 0x0100 =&amp;gt; 256 Byte Stack und Heap-Size: 0x0000 =&amp;gt; kein Heap). Mit &#039;&#039;&#039;&#039;&#039;Finish&#039;&#039;&#039;&#039;&#039; ist der Projekt Dialog abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_4.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danach sollten sich zwei neue Fenster öffnen, um die Debug-Eigenschaften fest zu legen.&lt;br /&gt;
Verwendet man ein Discovery Board/ST-Link müssen die Einstellungen wie auf dem Bild gewählt werden. Über den Button &#039;&#039;&#039;&#039;&#039;Settings&#039;&#039;&#039;&#039;&#039; öffnet sich das zweite Fenster, falls sich dieses nicht schon von alleine öffnen sollte. Nach den Schließen der Fenster über &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; ist der Projekt Dialog beendet und ein neues Projekt steht zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_5_1.png|Debug Eigenschaften 1. Fenster]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_5_2.png|Debug Eigenschaften 2. Fenster]]&lt;br /&gt;
&lt;br /&gt;
===2. CMSIS-Library und Startup-Code hinzufügen===&lt;br /&gt;
Wenn man sich, nachdem man ein neues Projekt in der IDE erstellt hat, die bereits vorhandenen Dateien im Projekt ansieht, stellt man fest, das bereits ein Ordner &#039;&#039;&#039;&#039;&#039;cmsis&#039;&#039;&#039;&#039;&#039; existiert, der einige wichtige Include-Dateien der CMSIS-Library enthält. Allerdings sind das wirklich nur die wichtigsten Include-Dateien der CMSIS-Library und dazu noch, die aus einer älternen Version. Ich ziehe es deshalb vor die &amp;quot;Mini-CMSIS-Libraray&amp;quot; und die &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c/.h&#039;&#039;&#039;&#039;&#039; Dateien des Projektes durch aktuellere Versionen zu ersetzen. So ist später auch die Integration  von anderen Libraries, wie z.B. der CMSIS-DSP-Libarary einfacher.  &lt;br /&gt;
&lt;br /&gt;
Zunächst gehen man in das Projekt-Verzeichnis und löscht:&lt;br /&gt;
*Den Ordner &#039;&#039;&#039;&#039;&#039;cmsis&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Alle Dateien im Include Verzeichnis &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; im &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner&lt;br /&gt;
&lt;br /&gt;
Außerdem entfernt man auch alle gelöschten Dateien in der IDE aus dem Projekt mit &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Rechts Klick -&amp;gt; Remove file from project&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Es sollte folgende Verzeichnis Struktur überbleiben:&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_6.png|Überbleibende Dateien]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Jetzt müssen die gelöschten Dateien durch die aktuelleren ersetzt werden.&lt;br /&gt;
&lt;br /&gt;
*Dazu kopieren man den gesamten Ordner &#039;&#039;&#039;&#039;&#039;CMSIS&#039;&#039;&#039;&#039;&#039; aus dem CMSIS Download in das Projekt Verzeichnis.&lt;br /&gt;
&lt;br /&gt;
*Aus dem Standard-Peripheral-Library Download kopiert man von &#039;&#039;&#039;&#039;&#039;Libraries\CMSIS\Device\ST\STM32F4xx\Include&#039;&#039;&#039;&#039;&#039; alle Dateien in den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projekt Verzeichnisses&lt;br /&gt;
&lt;br /&gt;
*Aus der Standard-Peripheral-Library kopieren man ebenfalls von &#039;&#039;&#039;&#039;&#039;Libraries\CMSIS\Device\ST\STM32F4xx\Source\Templates&#039;&#039;&#039;&#039;&#039; die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; in den &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner des Projekts&lt;br /&gt;
&lt;br /&gt;
Anschließend müssen die neuen Dateien in der IDE dem Projekt hinzugefügt werden. Dazu benutzt man &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Rechts Klick -&amp;gt; Add files&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
*Aus dem &#039;&#039;&#039;&#039;&#039;CMSIS&#039;&#039;&#039;&#039;&#039; Ordner im Projekt Verzeichnis werden aus den Unterorder &#039;&#039;&#039;&#039;&#039;Include&#039;&#039;&#039;&#039;&#039; folgende Dateien dem Projekt hinzugefügt:&lt;br /&gt;
**arm_common_tables.h&lt;br /&gt;
**arm_const_structs.h&lt;br /&gt;
**arm_math.h&lt;br /&gt;
**core_cm4.h&lt;br /&gt;
**core_cm4_simd.h&lt;br /&gt;
**core_cmFunc.h&lt;br /&gt;
**core_cmInstr.h&lt;br /&gt;
*Alle Dateien aus den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projektes&lt;br /&gt;
*Die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; aus dem &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner&lt;br /&gt;
&lt;br /&gt;
So sollte die Struktur dann aussehen:&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_7.png|Anwenungs-Grundgerüst]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Da einige Dateien der Libraries später bearbeitet werden müssen und Schreibgeschützt sind, weise ich hier schonmal darauf hin, das der Schreibschutz in der IDE über &#039;&#039;&#039;&#039;&#039;Rechts Klick auf die Datei -&amp;gt; Properties -&amp;gt; Häkchen bei &amp;quot;File is read only&amp;quot; entfernen&#039;&#039;&#039;&#039;&#039; entfert werden kann.&lt;br /&gt;
&lt;br /&gt;
Damit die IDE die Header-Dateien der CMSIS Library auch finden kann, weil diese ja nicht im standard Include Ordner &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; liegen, muss unter &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Build Options -&amp;gt; Search Directories&#039;&#039;&#039;&#039;&#039; der Pfad &#039;&#039;&#039;&#039;&#039;CMSIS\Include&#039;&#039;&#039;&#039;&#039; hinzugefügt werden.&lt;br /&gt;
&lt;br /&gt;
Compiliert man jetzt das Projekt mit &#039;&#039;&#039;&#039;&#039;F7&#039;&#039;&#039;&#039;&#039; gibt es ein paar Fehler Meldungen, weil keine Controller-Reihe ausgewählt wurde. Ebenfalls unter &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Build Options -&amp;gt; Compiler Settings -&amp;gt; #defines&#039;&#039;&#039;&#039;&#039; wird der Define &#039;&#039;&#039;&#039;&#039;STM32F40_41xxx&#039;&#039;&#039;&#039;&#039; hinzugefügt.&lt;br /&gt;
&lt;br /&gt;
Beim erneuten Compilieren sollten sich nun keine neuen Fehler ergeben.&lt;br /&gt;
&lt;br /&gt;
===Das erste Programm===&lt;br /&gt;
Nachdem ein grundsätzliches &amp;quot;Gerüst&amp;quot; fertig ist, kann man den ersten Code schreiben.&lt;br /&gt;
main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC-&amp;gt;AHB1ENR |= RCC_AHB1ENR_GPIODEN;    //Takt für GPIO aktivieren&lt;br /&gt;
    GPIOD-&amp;gt;MODER |= GPIO_MODER_MODER15_0;   //GPIOD Pin15 als Ausgang&lt;br /&gt;
    GPIOD-&amp;gt;BSRRL |= GPIO_BSRR_BS_15;        //GPIOD Pin15 auf High ziehen&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039; wird dann der Debugger gestartet. Hat der Debugger das Projekt erfolgreich übertragen kann die Ausführung mit &#039;&#039;&#039;&#039;&#039;F5&#039;&#039;&#039;&#039;&#039; begonnen werden.&lt;br /&gt;
&lt;br /&gt;
==Libraries einbinden/verwenden==&lt;br /&gt;
===Einbinden der Standard-Peripheral-Library===&lt;br /&gt;
Um nicht immer die einzelnen Register, wie im ersten &amp;quot;bare-metal&amp;quot; Beispiel, aus dem Reference-Manual zu suchen und zu beschreiben, gibt es von ST die Standard Peripheral Library, die diese Aufgaben übernimmt und mit der sich die &amp;quot;normale/grundlegende&amp;quot; (Alles außer USB und Ethernet) Peripherie recht einfach steuern lässt. Um die Library zu verwenden erzeugt man wie oben beschrieben ein neues Grundgerüst und kopiert als erstes den Ordner &#039;&#039;&#039;&#039;&#039;Libraries\STM32F4xx_StdPeriph_Driver&#039;&#039;&#039;&#039;&#039; aus dem Standard-Peripheral-Library Download in das Projekt-Verzeichnis. Außerdem muss man die Datei &#039;&#039;&#039;&#039;&#039;Project\STM32F4xx_StdPeriph_Templates\stm32f4xx_conf.h&#039;&#039;&#039;&#039;&#039; ebenfalls aus dem Standard-Peripheral-Library Download in den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projektes kopieren. In der IDE fügt man den Include-Path &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\inc&#039;&#039;&#039;&#039;&#039; hinzufügen, wie bei der CMSIS-Library (s.o.).&lt;br /&gt;
Außerdem muss noch &#039;&#039;&#039;&#039;&#039;USE_STDPERIPH_DRIVER&#039;&#039;&#039;&#039;&#039; als Define in der IDE hinzugefügt werden (s.o.).&lt;br /&gt;
Danach fügt man die Source- und Include-Dateien aus dem Ordner &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\inc&#039;&#039;&#039;&#039;&#039; und &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\src&#039;&#039;&#039;&#039;&#039; dem Project mit &#039;&#039;&#039;&#039;&#039;&amp;lt;Project Name&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Add files&#039;&#039;&#039;&#039;&#039; hinzu, allerdings nur die, für welche auch der Controller die entsprechende Peripherie besitzt. Beim STM32F4-Discovery Board / STM32F407VG Controller dürfen also nicht folgende Dateien nicht mit hinzugefügt werden, weil diese Peripherie nur bei anderen Controller vorhanden ist:&lt;br /&gt;
&lt;br /&gt;
*stm32f4xx_dma2d.c/.h&lt;br /&gt;
*stm32f4xx_fmc.c/.h&lt;br /&gt;
*stm32f4xx_ltdc.c/.h&lt;br /&gt;
*stm32f4xx_sai.c/.h&lt;br /&gt;
&lt;br /&gt;
Daraus resultiert folgende Struktur:&lt;br /&gt;
&lt;br /&gt;
[[Datei:stdperiphlib_2.png|Header-Struktur]] [[Datei:stdperiphlib_1.png|Source-Struktur]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Anschließen kann die Standard-Peripheral-Library benutz werden.&lt;br /&gt;
main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);&lt;br /&gt;
&lt;br /&gt;
    GPIO_InitTypeDef GPIOD_InitStructure;&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Mode = GPIO_Mode_OUT;     //Als Ausgang&lt;br /&gt;
    GPIOD_InitStructure.GPIO_OType = GPIO_OType_PP;    //Push-Pull Betrieb&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Pin = GPIO_Pin_15;        //Pin 15 (STM32F4-Discovery: Blaue LED)&lt;br /&gt;
    GPIOD_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;  //Kein Pull-Up oder Pull-Down Widerstand aktiviert&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Speed = GPIO_Speed_25MHz; //25MHz Update-Rate&lt;br /&gt;
    GPIO_Init(GPIOD, &amp;amp;GPIOD_InitStructure);&lt;br /&gt;
&lt;br /&gt;
    GPIO_SetBits(GPIOD, GPIO_Pin_15);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Startup-Code, Linker-Script, Takt, FPU usw.==&lt;br /&gt;
===Startup-Code===&lt;br /&gt;
Em::Blocks fügt standardmäßig einen Startup-Code mit in das Projekt ein. Die wichtigsten Dinge die darin erledigt werden sind folgende:&lt;br /&gt;
&lt;br /&gt;
*Stack und Heap wird angelgt&lt;br /&gt;
*Die Vector-Table wird angelegt&lt;br /&gt;
*Ein Default Reset-Handler wird implementiert, dieser erledigt folgende aufgaben:&lt;br /&gt;
**Kopieren der definierten Daten aus dem Flash in den SRAM&lt;br /&gt;
**&#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; wird aufgerfen, wenn __NO_SYSTEM_INIT nicht definiert ist&lt;br /&gt;
**Sprung in die &#039;&#039;&#039;&#039;&#039;main()&#039;&#039;&#039;&#039;&#039; Funktion&lt;br /&gt;
*Allen anderen Interrupt-Handler wird eine Default-Funktion &#039;&#039;&#039;&#039;&#039;def_irq_handler&#039;&#039;&#039;&#039;&#039; mit einer &#039;&#039;&#039;&#039;&#039;while(1)&#039;&#039;&#039;&#039;&#039;-Schleife zugewiesen, falls kein anderer Interrupt-Handler existiert.&lt;br /&gt;
&lt;br /&gt;
Normalerweise muss am Startup-Code nichts verändert werden.&lt;br /&gt;
&lt;br /&gt;
===Linker-Script===&lt;br /&gt;
===Der Takt===&lt;br /&gt;
Jeder Controller oder Prozessor braucht einen Takt, indem er die einzelnen Maschinen-Befehle abarbeiten kann.&lt;br /&gt;
Bei den STM32 Mikrocontrollern kann dieser Takt aus verschiedenen Quellen kommen:&lt;br /&gt;
&lt;br /&gt;
1. High Speed Internal Oszillator (HSI)&lt;br /&gt;
&lt;br /&gt;
2. High Speed External Oszillator (HSE)&lt;br /&gt;
&lt;br /&gt;
3. Low Speed Internal Oszillator (LSI)&lt;br /&gt;
&lt;br /&gt;
4. Low Speed External Oszillator (LSE)&lt;br /&gt;
&lt;br /&gt;
5. Phase-Locked Loop (PLL) (generiert den Takt aus den ersten vier Taktquellen durch Teiler und Faktoren)&lt;br /&gt;
&lt;br /&gt;
Nach einem Reset wird der Controller aus der HSI Taktquelle versorgt (16MHz beim STM32F407VG). Um die voll Performance des Controllers zu erreichen muss die PLL verwendet werden, welche den Takt durch geschickte Teiler und Faktoren vervielfältigt, sodass am Ende der Controller mit der maximalen Taktfrequenz läuft. Die notwendige Initialisierung der PLL findet in der Funktion &#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; statt. Die PLL erzeugt zunächst einen Basistakt:&lt;br /&gt;
&lt;br /&gt;
PLL_VCO = (F_HSE / PLL_M) * PLL_N&lt;br /&gt;
&lt;br /&gt;
Aus diesem Takt wird dann der Takt für den Controller-Kern abgeleitet:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = PLL_VCO / PLL_P&lt;br /&gt;
&lt;br /&gt;
Und der Takt für SDIO / USB / RNG (48MHz):&lt;br /&gt;
&lt;br /&gt;
48MHz = PLL_VCO / PLL_Q&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Durch weiter Teiler werden, die Takte für die einzelnen Busse erzeugt, da diese nicht alle beliebig schnell betrieben werden dürfen.&lt;br /&gt;
&lt;br /&gt;
Genaue Angaben findet man zu dem jeweiligen Clock-System des Controllers im Reference Manual.&lt;br /&gt;
&lt;br /&gt;
Ein Blick in den &amp;quot;Kommentar-Header&amp;quot; verrät, dass von einem externen (HSE) Oszillator von 25MHz ausgegangen wird, der die PLL versorgen soll.&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((25MHz / PLL_M(25)) * PLL_N(336)) / PLL_P(2) = 168MHz&lt;br /&gt;
&lt;br /&gt;
Allerdings stimmt diese Rechnung natürlich nur, wenn wirklich ein 25MHz Quarz am Controller angeschlossen ist. Auf dem STM32F4-Discovery Board befindet sich aber nur ein 8MHz Quarz. Demnach gilt:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((8MHz / PLL_M(25)) * PLL_N(336)) / PLL_P(2) = 53.76MHz&lt;br /&gt;
&lt;br /&gt;
Der Controller läuft also nur mit 53.76MHz, wenn wie ober beschrieben ein Projekt erstellt wird. Allerdings kann dieses Problem durch ändern von den betroffen Defines behoben werden:&lt;br /&gt;
 &lt;br /&gt;
*Dazu geht man in die &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; Datei und passt zur Vollständigkeit erstmal die zum Controller passende Tabelle im &amp;quot;Kommentar-Header&amp;quot; an (Z.57f):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      HSE Frequency(Hz)                      | 8000000&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      PLL_M                                  | 8&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Danach passt man den PPL_M Define (Z.254) an:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/************************* PLL Parameters *************************************/&lt;br /&gt;
/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */&lt;br /&gt;
#define PLL_M      8&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Außerdem muss man den HSE_VALUE Define in der &#039;&#039;&#039;&#039;&#039;inc/stm32f4xx.h&#039;&#039;&#039;&#039;&#039; angepasst werden (Z.122):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#if !defined  (HSE_VALUE)&lt;br /&gt;
  #define HSE_VALUE    ((uint32_t)8000000) /*!&amp;lt; Value of the External oscillator in Hz */&lt;br /&gt;
&lt;br /&gt;
#endif /* HSE_VALUE */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine neue Berechnung zeigt:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((8MHz / PLL_M(8)) * PLL_N(336)) / PLL_P(2) = 168MHz&lt;br /&gt;
&lt;br /&gt;
Jetzt läuft der Controller mit maximaler Geschwindigkeit.&lt;br /&gt;
&lt;br /&gt;
Die Theorie wird durch folgendes Programm verifiziert. Der geviertelte System-Takt SYSCLK wir am Pin PC9 ausgegeben. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);&lt;br /&gt;
&lt;br /&gt;
    GPIO_InitTypeDef GPIOC_InitStructure;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Mode = GPIO_Mode_AF;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_OType = GPIO_OType_PP;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Pin = GPIO_Pin_9;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;&lt;br /&gt;
    GPIO_Init(GPIOC, &amp;amp;GPIOC_InitStructure);&lt;br /&gt;
&lt;br /&gt;
    RCC_MCO2Config(RCC_MCO2Source_SYSCLK, RCC_MCO2Div_4);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Die FPU===&lt;br /&gt;
====Allgemeines====&lt;br /&gt;
Damit die FPU richtig verwendet wird, müssen normalerweise zwei Bedingungen erfüllt sein:&lt;br /&gt;
&lt;br /&gt;
1. Der Controller muss in der Initialisierung-Funktion &#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; in &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; die FPU Hardware-seitig aktivieren&lt;br /&gt;
&lt;br /&gt;
2. Damit die FPU auch was zu tuen bekommt, müssen vom Compiler FPU-Instructions erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
Die Em::Blocks IDE verwendet standardmäßig die FPU, wenn eine Vorhanden ist. Hier wird die FPU Hardware-seitig aktiviert (&#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; Z.341):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* FPU settings ------------------------------------------------------------*/&lt;br /&gt;
  #if (__FPU_PRESENT == 1) &amp;amp;&amp;amp; (__FPU_USED == 1)&lt;br /&gt;
    SCB-&amp;gt;CPACR |= ((3UL &amp;lt;&amp;lt; 10*2)|(3UL &amp;lt;&amp;lt; 11*2));  /* set CP10 and CP11 Full Access */&lt;br /&gt;
  #endif&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
__FPU_PRESENT wird in der &#039;&#039;&#039;&#039;&#039;stm32f4xx.h&#039;&#039;&#039;&#039;&#039; definiert.&lt;br /&gt;
__FPU_USED wird von der IDE übernommen (siehe Build-Log): &#039;&#039;&#039;&#039;&#039;-D__FPU_USED&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Außerdem wird der Compiler von der IDE standardmäßig mit dem Argument &#039;&#039;&#039;&#039;&#039;-mfloat-abi=hard&#039;&#039;&#039;&#039;&#039; aufgerufen, wodurch FPU-Instructions erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
====FPU abschalten====&lt;br /&gt;
Um die FPU ab zu schalten (Mir würde jetzt nur Strom sparen als Grund einfallen) geht man wie folgt vor:&lt;br /&gt;
&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick Build options -&amp;gt; Device -&amp;gt; Policy&#039;&#039;&#039;&#039;&#039; wählt man &#039;&#039;&#039;&#039;&#039;Use target settings&#039;&#039;&#039;&#039;&#039; und über nimmt die Einstellungen, die vorher dort eingetragen waren, allerdings lässt man das Feld &#039;&#039;&#039;&#039;&#039;FP-hardware&#039;&#039;&#039;&#039;&#039; frei.&lt;br /&gt;
&lt;br /&gt;
[[Datei:fpu_1.png|FPU Abschalten Schritt 1]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;Compiler Settings -&amp;gt; Policy&#039;&#039;&#039;&#039;&#039; wählt man dann &#039;&#039;&#039;&#039;&#039;Use target options only&#039;&#039;&#039;&#039;&#039;. Dann kann man unter &#039;&#039;&#039;&#039;&#039;Categories&#039;&#039;&#039;&#039;&#039; die Option &#039;&#039;&#039;&#039;&#039;ARM FPU architecture&#039;&#039;&#039;&#039;&#039; auswählen. Dort stehen dann drei Möglichkeiten für die FPU zur Verfügung:&lt;br /&gt;
&lt;br /&gt;
1. Software-FPU-Library für Gleitkomma-Berechnung verwenden - Keine FPU-Instructions werden generiert (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=soft&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
2. Eine Mischung aus Software- und Hardware-FPU wird verwendet (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=softfp&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
3. Hardware-FPU wird für Gleitkomma-Berechnungen verwendet (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=hard&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
[[Datei:fpu_2.png|FPU Abschalten Schritt 2]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Um die FPU ab zu schalten wählt man natürlich die erste Möglichkeit.&lt;br /&gt;
Bei der 2. und 3. Möglichkeit fügt die IDE auch den Define &#039;&#039;&#039;&#039;&#039;__FPU_USED&#039;&#039;&#039;&#039;&#039; hinzu. Bei Der ersten Möglichkeit nicht. Der Code muss also nicht verändert / auskommentiert werden.&lt;br /&gt;
&lt;br /&gt;
Um die FPU wieder zu aktivieren müssen alle Schritte wieder rückgängig gemacht werden.&lt;br /&gt;
&lt;br /&gt;
Am besten ist es einfach mal alle Möglichkeiten im Einzelschritt durch zu probieren. Dann stellt man schnell fest, ob die FPU aktiviert wir oder nicht. Ein Blick in den erweiterten &#039;&#039;&#039;&#039;&#039;Build-Log&#039;&#039;&#039;&#039;&#039; gibt auch schnell Aufschluss darüber, wie der Compiler aufgerufen wird (siehe Kapitel [http://www.mikrocontroller.net/articles/STM32_-_Einstieg_mit_Em::Blocks#Compilieren Compilieren]).&lt;br /&gt;
&lt;br /&gt;
====Test Programm für die FPU====&lt;br /&gt;
Hier ein kleines Testprogramm, dass misst wie viele Taktzyklen für eine Gleitkomma-Multiplikation gebraucht werden. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define CORE_SysTickEn()    (*((u32*)0xE0001000)) = 0x40000001&lt;br /&gt;
#define CORE_SysTickDis()   (*((u32*)0xE0001000)) = 0x40000000&lt;br /&gt;
#define CORE_GetSysTick()   (*((u32*)0xE0001004))&lt;br /&gt;
&lt;br /&gt;
uint32_t t1, t2, dt;&lt;br /&gt;
float x, y, z;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    x = 53.64f;&lt;br /&gt;
    y = 0.27f;&lt;br /&gt;
&lt;br /&gt;
    CORE_SysTickEn();&lt;br /&gt;
    t1 = CORE_GetSysTick();&lt;br /&gt;
&lt;br /&gt;
    z = x * y;&lt;br /&gt;
&lt;br /&gt;
    t2 = CORE_GetSysTick();&lt;br /&gt;
    CORE_SysTickDis();&lt;br /&gt;
&lt;br /&gt;
    dt = t2 - t1;&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mein Ergebnis:&lt;br /&gt;
*Mit Hardware-FPU:  dt = 25&lt;br /&gt;
*Ohne Hardware-FPU: dt = 83&lt;br /&gt;
&lt;br /&gt;
==Booten aus dem SRAM==&lt;br /&gt;
STM32 Controller haben die Möglichkeit Code aus dem Flash als auch aus dem SRAM auszuführen. Um eine Anwenung per Debugger in des SRAM zu laden sind nur wenige Schritte erforderlich:&lt;br /&gt;
&lt;br /&gt;
*Um das Linkerscript für den SRAM zu verwenden geht man zu: &#039;&#039;&#039;&#039;&#039;Build options... -&amp;gt; Device&#039;&#039;&#039;&#039;&#039; dort wählt man unter &#039;&#039;&#039;&#039;&#039;Policy&#039;&#039;&#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;Use target settings&#039;&#039;&#039;&#039;&#039; aus und übernimmt die vorherigen Einstellungen, nur unter &#039;&#039;&#039;&#039;&#039;Linker script*&#039;&#039;&#039;&#039;&#039; gibt man &#039;&#039;&#039;&#039;&#039;.\stm32f407vg_sram.ld&#039;&#039;&#039;&#039;&#039; an&lt;br /&gt;
&lt;br /&gt;
*Dann muss man noch unter &#039;&#039;&#039;&#039;&#039;Debug -&amp;gt; Interfaces -&amp;gt; Settings&#039;&#039;&#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;Vector table start&#039;&#039;&#039;&#039;&#039; auf 0x20000000 ändern und &#039;&#039;&#039;&#039;&#039;Execute from RAM&#039;&#039;&#039;&#039;&#039; auswählen.&lt;br /&gt;
&lt;br /&gt;
Anschließend kann man die Anwendung ganz normal debuggen. Nach einem Reset muss die Anwenung erneut mit dem Debugger gestartet werden.&lt;br /&gt;
&lt;br /&gt;
=Fortsetzung folgt..=&lt;br /&gt;
Kritik, Wünsche usw. sind gerne erwünscht, am besten hier in den Thread posten: [http://www.mikrocontroller.net/topic/323750 Neues STM32 Tutorial]&lt;br /&gt;
&lt;br /&gt;
[[Category:ARM]]&lt;br /&gt;
[[Category:STM32]]&lt;/div&gt;</summary>
		<author><name>Avrprogger</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=STM32_-_Einstieg_mit_Em::Blocks&amp;diff=81510</id>
		<title>STM32 - Einstieg mit Em::Blocks</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=STM32_-_Einstieg_mit_Em::Blocks&amp;diff=81510"/>
		<updated>2014-02-10T16:21:17Z</updated>

		<summary type="html">&lt;p&gt;Avrprogger: dfgf&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In diesem Tutorial werde ich versuchen, möglichst einfach, die ersten Schritte zur Entwicklung von STM32 Anwenungen mit der Em::Blocks IDE zu erklären. Hier soll nicht so stark auf die einzelnen Peripherie-Module der Controller eingegangen werden, sondern mehr auf die IDE und die verschieden Libraries, wie die CMSIS Library, die DSP-Library, die Standard-Peripheral-Library, die USB-Library und vllt. über Ethernet. Ich denke ein Kapitel zu FreeRTOS wird es auch geben. Auserdem steht im Vordergrund Sachen wie z.B. booten aus dem SRAM, In-Application-Programming, FPU, Core-Coupled-RAM usw. Mal sehn wie weit ich komme ;)&lt;br /&gt;
&lt;br /&gt;
==Die Entwicklungsumgebung==&lt;br /&gt;
===Hardware===&lt;br /&gt;
Zum testen der Anwendungen, benutze ich das STM32F4-Discovery Board, welches einen Debugger, Peripherie und natürlich einen STM32 Controller (STM32F407VGT6) enthält. Deshalb sind alle Beispiele hier für den STM32F407VG Controller ausgelegt, können aber meisten 1:1 auf andere Controller portiert werden. Ich werde auch möglichsts keine STM32F4-Discovery Board spezifischen Libraries verwenden, damit der Portierungs-Vorgang möglichsts einfach bleibt.&lt;br /&gt;
&lt;br /&gt;
===Software===&lt;br /&gt;
In diesem Tutorial verwende ich [http://www.emblocks.org/ Em::Blocks] als IDE. Em::Blocks ist eine kostenlose, uneingeschränkte IDE, die alle STM32 Mikrcontroller unterstützt und sehr einfach zu bedienen ist.&lt;br /&gt;
nach dem Download kann die IDE per Dialog, sehr einfach, installiert werden. Als Compiler beinhaltet Em::Blocks den &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
Die IDE unterstützt zurzeit den ST-Link, den J-Link und es gibt eine Generic-Vorlage, durch welche andere Debugger konfiguriert werden können.&lt;br /&gt;
&lt;br /&gt;
Außerdem muss noch der passende Treiber für den Debugger installiert werden. Verwendet man ein Discovery-Board muss der [http://www.st.com/web/catalog/tools/FM146/CL1984/SC724/SS1677/PF251168 ST-Link/V2]-Treiber heruntergeladen und installiert werden. (Die Installation muss evtl. als Administrator ausgeführt werden, da sonst die Installation unvollständig wird.) Nach der Installation des Treibers kann man den Debugger über die entsprechende USB Schnittstelle an den PC anschließen und es sollte die Meldung von Windows kommen, dass der richtige Treiber gefunden wurde.&lt;br /&gt;
&lt;br /&gt;
===Libraries===&lt;br /&gt;
Zum programmieren benötigt man noch die [http://www.arm.com/products/processors/cortex-m/cortex-microcontroller-software-interface-standard.php CMSIS] und die Standard-Peripheral-Library (z.B. für die F4 Controller [http://www.st.com/stonline/stappl/productcatalog/app?page=partNumberSearchPage&amp;amp;levelid=SS1577&amp;amp;parentid=1743&amp;amp;resourcetype=SW Standard-Peripheral-Library-F4]), die man am besten in einen Ordner (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\STM32&#039;&#039;&#039;&#039;&#039;) entpackt&lt;br /&gt;
&lt;br /&gt;
==Basis-Wissen zur IDE==&lt;br /&gt;
Einige Grundfunktionalitäten der IDE:&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von Dateien zum Projekt===&lt;br /&gt;
Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf &amp;lt;ProjektName&amp;gt; -&amp;gt; Add files...&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Enfernen von Dateien aus dem Projekt===&lt;br /&gt;
Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf die Datei / mehrere Dateien auswählen -&amp;gt; Remove file from project&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
Die Dateien werden lediglich aus dem Projekt entfernt und nicht von der Festplatte gelöscht.&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von Include-Pfaden===&lt;br /&gt;
Sofern die Include-Datei(en) nicht im standard Include-Ordner &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; des Projektes liegen, muss man den Pfad zum Projekt hinzufügen, damit der Compiler die Include-Dateien später auch finden kann. Man geht wie folgt vor: Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf &amp;lt;ProjektName&amp;gt; -&amp;gt; Build options... -&amp;gt; Search Directories -&amp;gt; Add&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Compilieren===&lt;br /&gt;
Entweder über das &#039;&#039;&#039;&#039;&#039;Build&#039;&#039;&#039;&#039;&#039; Menü oder über &#039;&#039;&#039;&#039;&#039;F7&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Um eine genau Ausgabe des Compiler-Aufrufes mit allen Argumenten zu bekommen, geht man im &#039;&#039;&#039;&#039;&#039;Settings&#039;&#039;&#039;&#039;&#039; Menü auf &#039;&#039;&#039;&#039;&#039;Tools...&#039;&#039;&#039;&#039;&#039; und dann auf &#039;&#039;&#039;&#039;&#039;Toolchain executables&#039;&#039;&#039;&#039;&#039;. Ganz unten, unter &#039;&#039;&#039;&#039;&#039;Logging&#039;&#039;&#039;&#039;&#039; kann man dann &#039;&#039;&#039;&#039;&#039;Full command line&#039;&#039;&#039;&#039;&#039; auswählen.&lt;br /&gt;
&lt;br /&gt;
===Debuggen===&lt;br /&gt;
*Als erstes den Debugger starten über das &#039;&#039;&#039;&#039;&#039;Debug&#039;&#039;&#039;&#039;&#039; Menü und &#039;&#039;&#039;&#039;&#039;Start/stop Debug Session&#039;&#039;&#039;&#039;&#039; oder über &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
*Danach läuft die Anwendung auf dem Controller und warten im &#039;&#039;&#039;&#039;&#039;Reset_Handler&#039;&#039;&#039;&#039;&#039; auf Einzelschritt- bzw. Run- Befehle (&#039;&#039;&#039;&#039;&#039;F5, F10, F11&#039;&#039;&#039;&#039;&#039; usw..(siehe &#039;&#039;&#039;&#039;&#039;Debug-Menü&#039;&#039;&#039;&#039;&#039; für alle Möglichkeiten))&lt;br /&gt;
&lt;br /&gt;
*Mit &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039; wird die Debug-Session auch wieder beendet&lt;br /&gt;
&lt;br /&gt;
*Unter &#039;&#039;&#039;&#039;&#039;Debug -&amp;gt; Interfaces -&amp;gt; Target settings&#039;&#039;&#039;&#039;&#039; können Eigenschaften, wie z.B &#039;&#039;&#039;&#039;&#039;Run to main()&#039;&#039;&#039;&#039;&#039; aktiviert werden.&lt;br /&gt;
&lt;br /&gt;
===Projekt als Template abspeichern===&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;File -&amp;gt; Save project as template...&#039;&#039;&#039;&#039;&#039;. Das Template erscheint dann im Projekt-Dialog unter &#039;&#039;&#039;&#039;&#039;User templates&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Das erste Projekt erstellen==&lt;br /&gt;
Hier erkläre ich, wie man am Besten (aus meiner Sicht), ein neues Projekt von Grund auf erstellt, sodass man hinterher, den Controller-Kern über die CMSIS-Library und die Peripherie über die Register steuern kann.&lt;br /&gt;
&lt;br /&gt;
===1. Projekt mit der IDE erstellen===&lt;br /&gt;
Nach der Installation der oben beschriebenen Komponenten erstellt man am besten ein Verzeichnis (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\EmBlocks&#039;&#039;&#039;&#039;&#039;), indem später alle Projekte gespeichert werden. Für Libraries kann man auch noch ein Verzeichnis (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\STM32&#039;&#039;&#039;&#039;&#039;) erstellen, wo alle Libraries gespeichert werden, die man für die Projekt brauchen.&lt;br /&gt;
&lt;br /&gt;
Als nächstes starten man EmBlocks. Bei dem ersten Start öffnet sich ein Fenster, wo verschiedene Compiler angezeigt werden, die Em::Blocks findet. Dort wählt man den &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039; aus und klickt &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039;. Nun sollte sich das Hauptfenster von Em::Blocks öffnen. Über &#039;&#039;&#039;&#039;&#039;Create a new Project&#039;&#039;&#039;&#039;&#039; oder &#039;&#039;&#039;&#039;&#039;File -&amp;gt; New -&amp;gt; Project&#039;&#039;&#039;&#039;&#039; ruft man den Projekt-Dialog auf und kann ein neues Projekt erzeugen.&lt;br /&gt;
&lt;br /&gt;
Auf der Ersten Seite wählen man den &#039;&#039;&#039;&#039;&#039;STmicro-ARM&#039;&#039;&#039;&#039;&#039; Projekt-Typ aus.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_1.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auf der nächsten Seite wird man darauf hingewiesen, dass das der entsprechende Projekt-Typ-Dialog ausgeführt wird. Hier kann man ein Häkchen bei &#039;&#039;&#039;&#039;&#039;Skip this page next time&#039;&#039;&#039;&#039;&#039; setzen und auf &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; klicken.&lt;br /&gt;
&lt;br /&gt;
Im nächsten Schritt wählen man das zuvor erstellt Verzeichnis unter &#039;&#039;&#039;&#039;&#039;Folder to create Project in&#039;&#039;&#039;&#039;&#039; aus, indem später alle Projekt gespeichert werden. Außerdem geben wir dem Projekt einen Namen (z.B. &#039;&#039;&#039;&#039;&#039;FirstProject&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_2.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danach muss man einen Compiler auswählen und bestimmen, welche Projekt-Konfigurationen erszeugt werden sollen. Unter &#039;&#039;&#039;&#039;&#039;Compiler&#039;&#039;&#039;&#039;&#039; wählt man &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039; und man kann das Häkchen bei &#039;&#039;&#039;&#039;&#039;Create &amp;quot;Release&amp;quot; configuration&#039;&#039;&#039;&#039;&#039; entfernen, da diese unnötig ist, die Debug-Konfiguration sollte eig. immer ausreichen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_3.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auf den folgenden Seite wird der Controller ausgewählt. Verwendet man ein STM32F4-Discovery Board müssen folgende Dinge gewählt werden: &#039;&#039;&#039;&#039;&#039;Cortex_M4 (F3xx - F4xx) -&amp;gt; STM32F4xx (Cortex M4 with FPU) -&amp;gt; STM32F407VG&#039;&#039;&#039;&#039;&#039;. Leider sind die Auswahl Möglichkeiten nicht ganz richtig, da auch die F3 Controller einen Cortex M4 Kern und eine FPU haben (Ist aber nicht so wichtig, ist nur eine formale Sache). Außerdem entfernt man das Häkchen bei &#039;&#039;&#039;&#039;&#039;Standard Peripherals Library&#039;&#039;&#039;&#039;&#039; (Wie man die Standard-Peripheral-Library einbindet und verwendet erkläre ich später). Man kann auch das Häkchen bei &#039;&#039;&#039;&#039;&#039;Create hex file for Realease target&#039;&#039;&#039;&#039;&#039; entfernen.&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;Stack Size&#039;&#039;&#039;&#039;&#039; und &#039;&#039;&#039;&#039;&#039;Heap Size&#039;&#039;&#039;&#039;&#039; wird die Größe von Stack und Heap festgelegt. Für eine erste Anwendung kann man die Einstellungen so lassen (Stack-Size: 0x0100 =&amp;gt; 256 Byte Stack und Heap-Size: 0x0000 =&amp;gt; kein Heap). Mit &#039;&#039;&#039;&#039;&#039;Finish&#039;&#039;&#039;&#039;&#039; ist der Projekt Dialog abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_4.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danach sollten sich zwei neue Fenster öffnen, um die Debug-Eigenschaften fest zu legen.&lt;br /&gt;
Verwendet man ein Discovery Board/ST-Link müssen die Einstellungen wie auf dem Bild gewählt werden. Über den Button &#039;&#039;&#039;&#039;&#039;Settings&#039;&#039;&#039;&#039;&#039; öffnet sich das zweite Fenster, falls sich dieses nicht schon von alleine öffnen sollte. Nach den Schließen der Fenster über &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; ist der Projekt Dialog beendet und ein neues Projekt steht zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_5_1.png|Debug Eigenschaften 1. Fenster]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_5_2.png|Debug Eigenschaften 2. Fenster]]&lt;br /&gt;
&lt;br /&gt;
===2. CMSIS-Library und Startup-Code hinzufügen===&lt;br /&gt;
Wenn man sich, nachdem man ein neues Projekt in der IDE erstellt hat, die bereits vorhandenen Dateien im Projekt ansieht, stellt man fest, das bereits ein Ordner &#039;&#039;&#039;&#039;&#039;cmsis&#039;&#039;&#039;&#039;&#039; existiert, der einige wichtige Include-Dateien der CMSIS-Library enthält. Allerdings sind das wirklich nur die wichtigsten Include-Dateien der CMSIS-Library und dazu noch, die aus einer älternen Version. Ich ziehe es deshalb vor die &amp;quot;Mini-CMSIS-Libraray&amp;quot; und die &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c/.h&#039;&#039;&#039;&#039;&#039; Dateien des Projektes durch aktuellere Versionen zu ersetzen. So ist später auch die Integration  von anderen Libraries, wie z.B. der CMSIS-DSP-Libarary einfacher.  &lt;br /&gt;
&lt;br /&gt;
Zunächst gehen man in das Projekt-Verzeichnis und löscht:&lt;br /&gt;
*Den Ordner &#039;&#039;&#039;&#039;&#039;cmsis&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Alle Dateien im Include Verzeichnis &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; im &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner&lt;br /&gt;
&lt;br /&gt;
Außerdem entfernt man auch alle gelöschten Dateien in der IDE aus dem Projekt mit &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Rechts Klick -&amp;gt; Remove file from project&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Es sollte folgende Verzeichnis Struktur überbleiben:&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_6.png|Überbleibende Dateien]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Jetzt müssen die gelöschten Dateien durch die aktuelleren ersetzt werden.&lt;br /&gt;
&lt;br /&gt;
*Dazu kopieren man den gesamten Ordner &#039;&#039;&#039;&#039;&#039;CMSIS&#039;&#039;&#039;&#039;&#039; aus dem CMSIS Download in das Projekt Verzeichnis.&lt;br /&gt;
&lt;br /&gt;
*Aus dem Standard-Peripheral-Library Download kopiert man von &#039;&#039;&#039;&#039;&#039;Libraries\CMSIS\Device\ST\STM32F4xx\Include&#039;&#039;&#039;&#039;&#039; alle Dateien in den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projekt Verzeichnisses&lt;br /&gt;
&lt;br /&gt;
*Aus der Standard-Peripheral-Library kopieren man ebenfalls von &#039;&#039;&#039;&#039;&#039;Libraries\CMSIS\Device\ST\STM32F4xx\Source\Templates&#039;&#039;&#039;&#039;&#039; die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; in den &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner des Projekts&lt;br /&gt;
&lt;br /&gt;
Anschließend müssen die neuen Dateien in der IDE dem Projekt hinzugefügt werden. Dazu benutzt man &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Rechts Klick -&amp;gt; Add files&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
*Aus dem &#039;&#039;&#039;&#039;&#039;CMSIS&#039;&#039;&#039;&#039;&#039; Ordner im Projekt Verzeichnis werden aus den Unterorder &#039;&#039;&#039;&#039;&#039;Include&#039;&#039;&#039;&#039;&#039; folgende Dateien dem Projekt hinzugefügt:&lt;br /&gt;
**arm_common_tables.h&lt;br /&gt;
**arm_const_structs.h&lt;br /&gt;
**arm_math.h&lt;br /&gt;
**core_cm4.h&lt;br /&gt;
**core_cm4_simd.h&lt;br /&gt;
**core_cmFunc.h&lt;br /&gt;
**core_cmInstr.h&lt;br /&gt;
*Alle Dateien aus den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projektes&lt;br /&gt;
*Die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; aus dem &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner&lt;br /&gt;
&lt;br /&gt;
So sollte die Struktur dann aussehen:&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_7.png|Anwenungs-Grundgerüst]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Da einige Dateien der Libraries später bearbeitet werden müssen und Schreibgeschützt sind, weise ich hier schonmal darauf hin, das der Schreibschutz in der IDE über &#039;&#039;&#039;&#039;&#039;Rechts Klick auf die Datei -&amp;gt; Properties -&amp;gt; Häkchen bei &amp;quot;File is read only&amp;quot; entfernen&#039;&#039;&#039;&#039;&#039; entfert werden kann.&lt;br /&gt;
&lt;br /&gt;
Damit die IDE die Header-Dateien der CMSIS Library auch finden kann, weil diese ja nicht im standard Include Ordner &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; liegen, muss unter &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Build Options -&amp;gt; Search Directories&#039;&#039;&#039;&#039;&#039; der Pfad &#039;&#039;&#039;&#039;&#039;CMSIS\Include&#039;&#039;&#039;&#039;&#039; hinzugefügt werden.&lt;br /&gt;
&lt;br /&gt;
Compiliert man jetzt das Projekt mit &#039;&#039;&#039;&#039;&#039;F7&#039;&#039;&#039;&#039;&#039; gibt es ein paar Fehler Meldungen, weil keine Controller-Reihe ausgewählt wurde. Ebenfalls unter &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Build Options -&amp;gt; Compiler Settings -&amp;gt; #defines&#039;&#039;&#039;&#039;&#039; wird der Define &#039;&#039;&#039;&#039;&#039;STM32F40_41xxx&#039;&#039;&#039;&#039;&#039; hinzugefügt.&lt;br /&gt;
&lt;br /&gt;
Beim erneuten Compilieren sollten sich nun keine neuen Fehler ergeben.&lt;br /&gt;
&lt;br /&gt;
===Das erste Programm===&lt;br /&gt;
Nachdem ein grundsätzliches &amp;quot;Gerüst&amp;quot; fertig ist, kann man den ersten Code schreiben.&lt;br /&gt;
main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC-&amp;gt;AHB1ENR |= RCC_AHB1ENR_GPIODEN;    //Takt für GPIO aktivieren&lt;br /&gt;
    GPIOD-&amp;gt;MODER |= GPIO_MODER_MODER15_0;   //GPIOD Pin15 als Ausgang&lt;br /&gt;
    GPIOD-&amp;gt;BSRRL |= GPIO_BSRR_BS_15;        //GPIOD Pin15 auf High ziehen&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039; wird dann der Debugger gestartet. Hat der Debugger das Projekt erfolgreich übertragen kann die Ausführung mit &#039;&#039;&#039;&#039;&#039;F5&#039;&#039;&#039;&#039;&#039; begonnen werden.&lt;br /&gt;
&lt;br /&gt;
==Libraries einbinden/verwenden==&lt;br /&gt;
===Einbinden der Standard-Peripheral-Library===&lt;br /&gt;
Um nicht immer die einzelnen Register, wie im ersten &amp;quot;bare-metal&amp;quot; Beispiel, aus dem Reference-Manual zu suchen und zu beschreiben, gibt es von ST die Standard Peripheral Library, die diese Aufgaben übernimmt und mit der sich die &amp;quot;normale/grundlegende&amp;quot; (Alles außer USB und Ethernet) Peripherie recht einfach steuern lässt. Um die Library zu verwenden erzeugt man wie oben beschrieben ein neues Grundgerüst und kopiert als erstes den Ordner &#039;&#039;&#039;&#039;&#039;Libraries\STM32F4xx_StdPeriph_Driver&#039;&#039;&#039;&#039;&#039; aus dem Standard-Peripheral-Library Download in das Projekt-Verzeichnis. Außerdem muss man die Datei &#039;&#039;&#039;&#039;&#039;Project\STM32F4xx_StdPeriph_Templates\stm32f4xx_conf.h&#039;&#039;&#039;&#039;&#039; ebenfalls aus dem Standard-Peripheral-Library Download in den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projektes kopieren. In der IDE fügt man den Include-Path &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\inc&#039;&#039;&#039;&#039;&#039; hinzufügen, wie bei der CMSIS-Library (s.o.).&lt;br /&gt;
Außerdem muss noch &#039;&#039;&#039;&#039;&#039;USE_STDPERIPH_DRIVER&#039;&#039;&#039;&#039;&#039; als Define in der IDE hinzugefügt werden (s.o.).&lt;br /&gt;
Danach fügt man die Source- und Include-Dateien aus dem Ordner &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\inc&#039;&#039;&#039;&#039;&#039; und &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\src&#039;&#039;&#039;&#039;&#039; dem Project mit &#039;&#039;&#039;&#039;&#039;&amp;lt;Project Name&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Add files&#039;&#039;&#039;&#039;&#039; hinzu, allerdings nur die, für welche auch der Controller die entsprechende Peripherie besitzt. Beim STM32F4-Discovery Board / STM32F407VG Controller dürfen also nicht folgende Dateien nicht mit hinzugefügt werden, weil diese Peripherie nur bei anderen Controller vorhanden ist:&lt;br /&gt;
&lt;br /&gt;
*stm32f4xx_dma2d.c/.h&lt;br /&gt;
*stm32f4xx_fmc.c/.h&lt;br /&gt;
*stm32f4xx_ltdc.c/.h&lt;br /&gt;
*stm32f4xx_sai.c/.h&lt;br /&gt;
&lt;br /&gt;
Daraus resultiert folgende Struktur:&lt;br /&gt;
&lt;br /&gt;
[[Datei:stdperiphlib_2.png|Header-Struktur]] [[Datei:stdperiphlib_1.png|Source-Struktur]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Anschließen kann die Standard-Peripheral-Library benutz werden.&lt;br /&gt;
main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);&lt;br /&gt;
&lt;br /&gt;
    GPIO_InitTypeDef GPIOD_InitStructure;&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Mode = GPIO_Mode_OUT;     //Als Ausgang&lt;br /&gt;
    GPIOD_InitStructure.GPIO_OType = GPIO_OType_PP;    //Push-Pull Betrieb&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Pin = GPIO_Pin_15;        //Pin 15 (STM32F4-Discovery: Blaue LED)&lt;br /&gt;
    GPIOD_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;  //Kein Pull-Up oder Pull-Down Widerstand aktiviert&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Speed = GPIO_Speed_25MHz; //25MHz Update-Rate&lt;br /&gt;
    GPIO_Init(GPIOD, &amp;amp;GPIOD_InitStructure);&lt;br /&gt;
&lt;br /&gt;
    GPIO_SetBits(GPIOD, GPIO_Pin_15);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Startup-Code, Linker-Script, Takt, FPU usw.==&lt;br /&gt;
===Startup-Code===&lt;br /&gt;
===Linker-Script===&lt;br /&gt;
===Der Takt===&lt;br /&gt;
Jeder Controller oder Prozessor braucht einen Takt, indem er die einzelnen Maschinen-Befehle abarbeiten kann.&lt;br /&gt;
Bei den STM32 Mikrocontrollern kann dieser Takt aus verschiedenen Quellen kommen:&lt;br /&gt;
&lt;br /&gt;
1. High Speed Internal Oszillator (HSI)&lt;br /&gt;
&lt;br /&gt;
2. High Speed External Oszillator (HSE)&lt;br /&gt;
&lt;br /&gt;
3. Low Speed Internal Oszillator (LSI)&lt;br /&gt;
&lt;br /&gt;
4. Low Speed External Oszillator (LSE)&lt;br /&gt;
&lt;br /&gt;
5. Phase-Locked Loop (PLL) (generiert den Takt aus den ersten vier Taktquellen durch Teiler und Faktoren)&lt;br /&gt;
&lt;br /&gt;
Nach einem Reset wird der Controller aus der HSI Taktquelle versorgt (16MHz beim STM32F407VG). Um die voll Performance des Controllers zu erreichen muss die PLL verwendet werden, welche den Takt durch geschickte Teiler und Faktoren vervielfältigt, sodass am Ende der Controller mit der maximalen Taktfrequenz läuft. Die notwendige Initialisierung der PLL findet in der Funktion &#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; statt. Die PLL erzeugt zunächst einen Basistakt:&lt;br /&gt;
&lt;br /&gt;
PLL_VCO = (F_HSE / PLL_M) * PLL_N&lt;br /&gt;
&lt;br /&gt;
Aus diesem Takt wird dann der Takt für den Controller-Kern abgeleitet:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = PLL_VCO / PLL_P&lt;br /&gt;
&lt;br /&gt;
Und der Takt für SDIO / USB / RNG (48MHz):&lt;br /&gt;
&lt;br /&gt;
48MHz = PLL_VCO / PLL_Q&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Durch weiter Teiler werden, die Takte für die einzelnen Busse erzeugt, da diese nicht alle beliebig schnell betrieben werden dürfen.&lt;br /&gt;
&lt;br /&gt;
Genaue Angaben findet man zu dem jeweiligen Clock-System des Controllers im Reference Manual.&lt;br /&gt;
&lt;br /&gt;
Ein Blick in den &amp;quot;Kommentar-Header&amp;quot; verrät, dass von einem externen (HSE) Oszillator von 25MHz ausgegangen wird, der die PLL versorgen soll.&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((25MHz / PLL_M(25)) * PLL_N(336)) / PLL_P(2) = 168MHz&lt;br /&gt;
&lt;br /&gt;
Allerdings stimmt diese Rechnung natürlich nur, wenn wirklich ein 25MHz Quarz am Controller angeschlossen ist. Auf dem STM32F4-Discovery Board befindet sich aber nur ein 8MHz Quarz. Demnach gilt:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((8MHz / PLL_M(25)) * PLL_N(336)) / PLL_P(2) = 53.76MHz&lt;br /&gt;
&lt;br /&gt;
Der Controller läuft also nur mit 53.76MHz, wenn wie ober beschrieben ein Projekt erstellt wird. Allerdings kann dieses Problem durch ändern von den betroffen Defines behoben werden:&lt;br /&gt;
 &lt;br /&gt;
*Dazu geht man in die &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; Datei und passt zur Vollständigkeit erstmal die zum Controller passende Tabelle im &amp;quot;Kommentar-Header&amp;quot; an (Z.57f):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      HSE Frequency(Hz)                      | 8000000&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      PLL_M                                  | 8&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Danach passt man den PPL_M Define (Z.254) an:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/************************* PLL Parameters *************************************/&lt;br /&gt;
/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */&lt;br /&gt;
#define PLL_M      8&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Außerdem muss man den HSE_VALUE Define in der &#039;&#039;&#039;&#039;&#039;inc/stm32f4xx.h&#039;&#039;&#039;&#039;&#039; angepasst werden (Z.122):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#if !defined  (HSE_VALUE)&lt;br /&gt;
  #define HSE_VALUE    ((uint32_t)8000000) /*!&amp;lt; Value of the External oscillator in Hz */&lt;br /&gt;
&lt;br /&gt;
#endif /* HSE_VALUE */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine neue Berechnung zeigt:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((8MHz / PLL_M(8)) * PLL_N(336)) / PLL_P(2) = 168MHz&lt;br /&gt;
&lt;br /&gt;
Jetzt läuft der Controller mit maximaler Geschwindigkeit.&lt;br /&gt;
&lt;br /&gt;
Die Theorie wird durch folgendes Programm verifiziert. Der geviertelte System-Takt SYSCLK wir am Pin PC9 ausgegeben. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);&lt;br /&gt;
&lt;br /&gt;
    GPIO_InitTypeDef GPIOC_InitStructure;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Mode = GPIO_Mode_AF;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_OType = GPIO_OType_PP;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Pin = GPIO_Pin_9;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;&lt;br /&gt;
    GPIO_Init(GPIOC, &amp;amp;GPIOC_InitStructure);&lt;br /&gt;
&lt;br /&gt;
    RCC_MCO2Config(RCC_MCO2Source_SYSCLK, RCC_MCO2Div_4);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Die FPU===&lt;br /&gt;
====Allgemeines====&lt;br /&gt;
Damit die FPU richtig verwendet wird, müssen normalerweise zwei Bedingungen erfüllt sein:&lt;br /&gt;
&lt;br /&gt;
1. Der Controller muss in der Initialisierung-Funktion &#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; in &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; die FPU Hardware-seitig aktivieren&lt;br /&gt;
&lt;br /&gt;
2. Damit die FPU auch was zu tuen bekommt, müssen vom Compiler FPU-Instructions erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
Die Em::Blocks IDE verwendet standardmäßig die FPU, wenn eine Vorhanden ist. Hier wird die FPU Hardware-seitig aktiviert (&#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; Z.341):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* FPU settings ------------------------------------------------------------*/&lt;br /&gt;
  #if (__FPU_PRESENT == 1) &amp;amp;&amp;amp; (__FPU_USED == 1)&lt;br /&gt;
    SCB-&amp;gt;CPACR |= ((3UL &amp;lt;&amp;lt; 10*2)|(3UL &amp;lt;&amp;lt; 11*2));  /* set CP10 and CP11 Full Access */&lt;br /&gt;
  #endif&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
__FPU_PRESENT wird in der &#039;&#039;&#039;&#039;&#039;stm32f4xx.h&#039;&#039;&#039;&#039;&#039; definiert.&lt;br /&gt;
__FPU_USED wird von der IDE übernommen (siehe Build-Log): &#039;&#039;&#039;&#039;&#039;-D__FPU_USED&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Außerdem wird der Compiler von der IDE standardmäßig mit dem Argument &#039;&#039;&#039;&#039;&#039;-mfloat-abi=hard&#039;&#039;&#039;&#039;&#039; aufgerufen, wodurch FPU-Instructions erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
====FPU abschalten====&lt;br /&gt;
Um die FPU ab zu schalten (Mir würde jetzt nur Strom sparen als Grund einfallen) geht man wie folgt vor:&lt;br /&gt;
&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick Build options -&amp;gt; Device -&amp;gt; Policy&#039;&#039;&#039;&#039;&#039; wählt man &#039;&#039;&#039;&#039;&#039;Use target settings&#039;&#039;&#039;&#039;&#039; und über nimmt die Einstellungen, die vorher dort eingetragen waren, allerdings lässt man das Feld &#039;&#039;&#039;&#039;&#039;FP-hardware&#039;&#039;&#039;&#039;&#039; frei.&lt;br /&gt;
&lt;br /&gt;
[[Datei:fpu_1.png|FPU Abschalten Schritt 1]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;Compiler Settings -&amp;gt; Policy&#039;&#039;&#039;&#039;&#039; wählt man dann &#039;&#039;&#039;&#039;&#039;Use target options only&#039;&#039;&#039;&#039;&#039;. Dann kann man unter &#039;&#039;&#039;&#039;&#039;Categories&#039;&#039;&#039;&#039;&#039; die Option &#039;&#039;&#039;&#039;&#039;ARM FPU architecture&#039;&#039;&#039;&#039;&#039; auswählen. Dort stehen dann drei Möglichkeiten für die FPU zur Verfügung:&lt;br /&gt;
&lt;br /&gt;
1. Software-FPU-Library für Gleitkomma-Berechnung verwenden - Keine FPU-Instructions werden generiert (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=soft&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
2. Eine Mischung aus Software- und Hardware-FPU wird verwendet (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=softfp&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
3. Hardware-FPU wird für Gleitkomma-Berechnungen verwendet (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=hard&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
[[Datei:fpu_2.png|FPU Abschalten Schritt 2]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Um die FPU ab zu schalten wählt man natürlich die erste Möglichkeit.&lt;br /&gt;
Bei der 2. und 3. Möglichkeit fügt die IDE auch den Define &#039;&#039;&#039;&#039;&#039;__FPU_USED&#039;&#039;&#039;&#039;&#039; hinzu. Bei Der ersten Möglichkeit nicht. Der Code muss also nicht verändert / auskommentiert werden.&lt;br /&gt;
&lt;br /&gt;
Um die FPU wieder zu aktivieren müssen alle Schritte wieder rückgängig gemacht werden.&lt;br /&gt;
&lt;br /&gt;
Am besten ist es einfach mal alle Möglichkeiten im Einzelschritt durch zu probieren. Dann stellt man schnell fest, ob die FPU aktiviert wir oder nicht. Ein Blick in den erweiterten &#039;&#039;&#039;&#039;&#039;Build-Log&#039;&#039;&#039;&#039;&#039; gibt auch schnell Aufschluss darüber, wie der Compiler aufgerufen wird (siehe Kapitel [http://www.mikrocontroller.net/articles/STM32_-_Einstieg_mit_Em::Blocks#Compilieren Compilieren]).&lt;br /&gt;
&lt;br /&gt;
====Test Programm für die FPU====&lt;br /&gt;
Hier ein kleines Testprogramm, dass misst wie viele Taktzyklen für eine Gleitkomma-Multiplikation gebraucht werden. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define CORE_SysTickEn()    (*((u32*)0xE0001000)) = 0x40000001&lt;br /&gt;
#define CORE_SysTickDis()   (*((u32*)0xE0001000)) = 0x40000000&lt;br /&gt;
#define CORE_GetSysTick()   (*((u32*)0xE0001004))&lt;br /&gt;
&lt;br /&gt;
uint32_t t1, t2, dt;&lt;br /&gt;
float x, y, z;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    x = 53.64f;&lt;br /&gt;
    y = 0.27f;&lt;br /&gt;
&lt;br /&gt;
    CORE_SysTickEn();&lt;br /&gt;
    t1 = CORE_GetSysTick();&lt;br /&gt;
&lt;br /&gt;
    z = x * y;&lt;br /&gt;
&lt;br /&gt;
    t2 = CORE_GetSysTick();&lt;br /&gt;
    CORE_SysTickDis();&lt;br /&gt;
&lt;br /&gt;
    dt = t2 - t1;&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mein Ergebnis:&lt;br /&gt;
*Mit Hardware-FPU:  dt = 25&lt;br /&gt;
*Ohne Hardware-FPU: dt = 83&lt;br /&gt;
&lt;br /&gt;
==Booten aus dem SRAM==&lt;br /&gt;
STM32 Controller haben die Möglichkeit Code aus dem Flash als auch aus dem SRAM auszuführen. Um eine Anwenung per Debugger in des SRAM zu laden sind nur wenige Schritte erforderlich:&lt;br /&gt;
&lt;br /&gt;
*Um das Linkerscript für den SRAM zu verwenden geht man zu: &#039;&#039;&#039;&#039;&#039;Build options... -&amp;gt; Device&#039;&#039;&#039;&#039;&#039; dort wählt man unter &#039;&#039;&#039;&#039;&#039;Policy&#039;&#039;&#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;Use target settings&#039;&#039;&#039;&#039;&#039; aus und übernimmt die vorherigen Einstellungen, nur unter &#039;&#039;&#039;&#039;&#039;Linker script*&#039;&#039;&#039;&#039;&#039; gibt man &#039;&#039;&#039;&#039;&#039;.\stm32f407vg_sram.ld&#039;&#039;&#039;&#039;&#039; an&lt;br /&gt;
&lt;br /&gt;
*Dann muss man noch unter &#039;&#039;&#039;&#039;&#039;Debug -&amp;gt; Interfaces -&amp;gt; Settings&#039;&#039;&#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;Vector table start&#039;&#039;&#039;&#039;&#039; auf 0x20000000 ändern und &#039;&#039;&#039;&#039;&#039;Execute from RAM&#039;&#039;&#039;&#039;&#039; auswählen.&lt;br /&gt;
&lt;br /&gt;
Anschließend kann man die Anwendung ganz normal debuggen. Nach einem Reset muss die Anwenung erneut mit dem Debugger gestartet werden.&lt;br /&gt;
&lt;br /&gt;
=Fortsetzung folgt..=&lt;br /&gt;
Kritik, Wünsche usw. sind gerne erwünscht, am besten hier in den Thread posten: [http://www.mikrocontroller.net/topic/323750 Neues STM32 Tutorial]&lt;br /&gt;
&lt;br /&gt;
[[Category:ARM]]&lt;br /&gt;
[[Category:STM32]]&lt;/div&gt;</summary>
		<author><name>Avrprogger</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=STM32_-_Einstieg_mit_Em::Blocks&amp;diff=81509</id>
		<title>STM32 - Einstieg mit Em::Blocks</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=STM32_-_Einstieg_mit_Em::Blocks&amp;diff=81509"/>
		<updated>2014-02-10T16:20:29Z</updated>

		<summary type="html">&lt;p&gt;Avrprogger: cvb&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In diesem Tutorial werde ich versuchen, möglichst einfach, die ersten Schritte zur Entwicklung von STM32 Anwenungen mit der Em::Blocks IDE zu erklären. Hier soll nicht so stark auf die einzelnen Peripherie-Module der Controller eingegangen werden, sondern mehr auf die IDE und die verschieden Libraries, wie die CMSIS Library, die DSP-Library, die Standard-Peripheral-Library, die USB-Library und vllt. über Ethernet. Ich denke ein Kapitel zu FreeRTOS wird es auch geben. Auserdem steht im Vordergrund Sachen wie z.B. booten aus dem SRAM, In-Application-Programming, FPU, Core-Coupled-RAM usw. Mal sehn wie weit ich komme ;)&lt;br /&gt;
&lt;br /&gt;
==Die Entwicklungsumgebung==&lt;br /&gt;
===Hardware===&lt;br /&gt;
Zum testen der Anwendungen, benutze ich das STM32F4-Discovery Board, welches einen Debugger, Peripherie und natürlich einen STM32 Controller (STM32F407VGT6) enthält. Deshalb sind alle Beispiele hier für den STM32F407VG Controller ausgelegt, können aber meisten 1:1 auf andere Controller portiert werden. Ich werde auch möglichsts keine STM32F4-Discovery Board spezifischen Libraries verwenden, damit der Portierungs-Vorgang möglichsts einfach bleibt.&lt;br /&gt;
&lt;br /&gt;
===Software===&lt;br /&gt;
In diesem Tutorial verwende ich [http://www.emblocks.org/ Em::Blocks] als IDE. Em::Blocks ist eine kostenlose, uneingeschränkte IDE, die alle STM32 Mikrcontroller unterstützt und sehr einfach zu bedienen ist.&lt;br /&gt;
nach dem Download kann die IDE per Dialog, sehr einfach, installiert werden. Als Compiler beinhaltet Em::Blocks den &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
Die IDE unterstützt zurzeit den ST-Link, den J-Link und es gibt eine Generic-Vorlage, durch welche andere Debugger konfiguriert werden können.&lt;br /&gt;
&lt;br /&gt;
Außerdem muss noch der passende Treiber für den Debugger installiert werden. Verwendet man ein Discovery-Board muss der [http://www.st.com/web/catalog/tools/FM146/CL1984/SC724/SS1677/PF251168 ST-Link/V2]-Treiber heruntergeladen und installiert werden. (Die Installation muss evtl. als Administrator ausgeführt werden, da sonst die Installation unvollständig wird.) Nach der Installation des Treibers kann man den Debugger über die entsprechende USB Schnittstelle an den PC anschließen und es sollte die Meldung von Windows kommen, dass der richtige Treiber gefunden wurde.&lt;br /&gt;
&lt;br /&gt;
===Libraries===&lt;br /&gt;
Zum programmieren benötigt man noch die [http://www.arm.com/products/processors/cortex-m/cortex-microcontroller-software-interface-standard.php CMSIS] und die Standard-Peripheral-Library (z.B. für die F4 Controller [http://www.st.com/stonline/stappl/productcatalog/app?page=partNumberSearchPage&amp;amp;levelid=SS1577&amp;amp;parentid=1743&amp;amp;resourcetype=SW Standard-Peripheral-Library-F4]), die man am besten in einen Ordner (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\STM32&#039;&#039;&#039;&#039;&#039;) entpackt&lt;br /&gt;
&lt;br /&gt;
==Basis-Wissen zur IDE==&lt;br /&gt;
Einige Grundfunktionalitäten der IDE:&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von Dateien zum Projekt===&lt;br /&gt;
Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf &amp;lt;ProjektName&amp;gt; -&amp;gt; Add files...&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Enfernen von Dateien aus dem Projekt===&lt;br /&gt;
Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf die Datei / mehrere Dateien auswählen -&amp;gt; Remove file from project&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
Die Dateien werden lediglich aus dem Projekt entfernt und nicht von der Festplatte gelöscht.&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von Include-Pfaden===&lt;br /&gt;
Sofern die Include-Datei(en) nicht im standard Include-Ordner &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; des Projektes liegen, muss man den Pfad zum Projekt hinzufügen, damit der Compiler die Include-Dateien später auch finden kann. Man geht wie folgt vor: Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf &amp;lt;ProjektName&amp;gt; -&amp;gt; Build options... -&amp;gt; Search Directories -&amp;gt; Add&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Compilieren===&lt;br /&gt;
Entweder über das &#039;&#039;&#039;&#039;&#039;Build&#039;&#039;&#039;&#039;&#039; Menü oder über &#039;&#039;&#039;&#039;&#039;F7&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Um eine genau Ausgabe des Compiler-Aufrufes mit allen Argumenten zu bekommen, geht man im &#039;&#039;&#039;&#039;&#039;Settings&#039;&#039;&#039;&#039;&#039; Menü auf &#039;&#039;&#039;&#039;&#039;Tools...&#039;&#039;&#039;&#039;&#039; und dann auf &#039;&#039;&#039;&#039;&#039;Toolchain executables&#039;&#039;&#039;&#039;&#039;. Ganz unten, unter &#039;&#039;&#039;&#039;&#039;Logging&#039;&#039;&#039;&#039;&#039; kann man dann &#039;&#039;&#039;&#039;&#039;Full command line&#039;&#039;&#039;&#039;&#039; auswählen.&lt;br /&gt;
&lt;br /&gt;
===Debuggen===&lt;br /&gt;
*Als erstes den Debugger starten über das &#039;&#039;&#039;&#039;&#039;Debug&#039;&#039;&#039;&#039;&#039; Menü und &#039;&#039;&#039;&#039;&#039;Start/stop Debug Session&#039;&#039;&#039;&#039;&#039; oder über &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
*Danach läuft die Anwendung auf dem Controller und warten im &#039;&#039;&#039;&#039;&#039;Reset_Handler&#039;&#039;&#039;&#039;&#039; auf Einzelschritt- bzw. Run- Befehle (&#039;&#039;&#039;&#039;&#039;F5, F10, F11&#039;&#039;&#039;&#039;&#039; usw..(siehe &#039;&#039;&#039;&#039;&#039;Debug-Menü&#039;&#039;&#039;&#039;&#039; für alle Möglichkeiten))&lt;br /&gt;
&lt;br /&gt;
*Mit &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039; wird die Debug-Session auch wieder beendet&lt;br /&gt;
&lt;br /&gt;
*Unter &#039;&#039;&#039;&#039;&#039;Debug -&amp;gt; Interfaces -&amp;gt; Target settings&#039;&#039;&#039;&#039;&#039; können Eigenschaften, wie z.B &#039;&#039;&#039;&#039;&#039;Run to main()&#039;&#039;&#039;&#039;&#039; aktiviert werden.&lt;br /&gt;
&lt;br /&gt;
===Projekt als Template abspeichern===&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;File -&amp;gt; Save project as template...&#039;&#039;&#039;&#039;&#039;. Das Template erscheint dann im Projekt-Dialog unter &#039;&#039;&#039;&#039;&#039;User templates&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Das erste Projekt erstellen==&lt;br /&gt;
Hier erkläre ich, wie man am Besten (aus meiner Sicht), ein neues Projekt von Grund auf erstellt, sodass man hinterher, den Controller-Kern über die CMSIS-Library und die Peripherie über die Register steuern kann.&lt;br /&gt;
&lt;br /&gt;
===1. Projekt mit der IDE erstellen===&lt;br /&gt;
Nach der Installation der oben beschriebenen Komponenten erstellt man am besten ein Verzeichnis (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\EmBlocks&#039;&#039;&#039;&#039;&#039;), indem später alle Projekte gespeichert werden. Für Libraries kann man auch noch ein Verzeichnis (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\STM32&#039;&#039;&#039;&#039;&#039;) erstellen, wo alle Libraries gespeichert werden, die man für die Projekt brauchen.&lt;br /&gt;
&lt;br /&gt;
Als nächstes starten man EmBlocks. Bei dem ersten Start öffnet sich ein Fenster, wo verschiedene Compiler angezeigt werden, die Em::Blocks findet. Dort wählt man den &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039; aus und klickt &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039;. Nun sollte sich das Hauptfenster von Em::Blocks öffnen. Über &#039;&#039;&#039;&#039;&#039;Create a new Project&#039;&#039;&#039;&#039;&#039; oder &#039;&#039;&#039;&#039;&#039;File -&amp;gt; New -&amp;gt; Project&#039;&#039;&#039;&#039;&#039; ruft man den Projekt-Dialog auf und kann ein neues Projekt erzeugen.&lt;br /&gt;
&lt;br /&gt;
Auf der Ersten Seite wählen man den &#039;&#039;&#039;&#039;&#039;STmicro-ARM&#039;&#039;&#039;&#039;&#039; Projekt-Typ aus.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_1.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auf der nächsten Seite wird man darauf hingewiesen, dass das der entsprechende Projekt-Typ-Dialog ausgeführt wird. Hier kann man ein Häkchen bei &#039;&#039;&#039;&#039;&#039;Skip this page next time&#039;&#039;&#039;&#039;&#039; setzen und auf &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; klicken.&lt;br /&gt;
&lt;br /&gt;
Im nächsten Schritt wählen man das zuvor erstellt Verzeichnis unter &#039;&#039;&#039;&#039;&#039;Folder to create Project in&#039;&#039;&#039;&#039;&#039; aus, indem später alle Projekt gespeichert werden. Außerdem geben wir dem Projekt einen Namen (z.B. &#039;&#039;&#039;&#039;&#039;FirstProject&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_2.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danach muss man einen Compiler auswählen und bestimmen, welche Projekt-Konfigurationen erszeugt werden sollen. Unter &#039;&#039;&#039;&#039;&#039;Compiler&#039;&#039;&#039;&#039;&#039; wählt man &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039; und man kann das Häkchen bei &#039;&#039;&#039;&#039;&#039;Create &amp;quot;Release&amp;quot; configuration&#039;&#039;&#039;&#039;&#039; entfernen, da diese unnötig ist, die Debug-Konfiguration sollte eig. immer ausreichen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_3.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auf den folgenden Seite wird der Controller ausgewählt. Verwendet man ein STM32F4-Discovery Board müssen folgende Dinge gewählt werden: &#039;&#039;&#039;&#039;&#039;Cortex_M4 (F3xx - F4xx) -&amp;gt; STM32F4xx (Cortex M4 with FPU) -&amp;gt; STM32F407VG&#039;&#039;&#039;&#039;&#039;. Leider sind die Auswahl Möglichkeiten nicht ganz richtig, da auch die F3 Controller einen Cortex M4 Kern und eine FPU haben (Ist aber nicht so wichtig, ist nur eine formale Sache). Außerdem entfernt man das Häkchen bei &#039;&#039;&#039;&#039;&#039;Standard Peripherals Library&#039;&#039;&#039;&#039;&#039; (Wie man die Standard-Peripheral-Library einbindet und verwendet erkläre ich später). Man kann auch das Häkchen bei &#039;&#039;&#039;&#039;&#039;Create hex file for Realease target&#039;&#039;&#039;&#039;&#039; entfernen.&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;Stack Size&#039;&#039;&#039;&#039;&#039; und &#039;&#039;&#039;&#039;&#039;Heap Size&#039;&#039;&#039;&#039;&#039; wird die Größe von Stack und Heap festgelegt. Für eine erste Anwendung kann man die Einstellungen so lassen (Stack-Size: 0x0100 =&amp;gt; 256 Byte Stack und Heap-Size: 0x0000 =&amp;gt; kein Heap). Mit &#039;&#039;&#039;&#039;&#039;Finish&#039;&#039;&#039;&#039;&#039; ist der Projekt Dialog abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_4.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danach sollten sich zwei neue Fenster öffnen, um die Debug-Eigenschaften fest zu legen.&lt;br /&gt;
Verwendet man ein Discovery Board/ST-Link müssen die Einstellungen wie auf dem Bild gewählt werden. Über den Button &#039;&#039;&#039;&#039;&#039;Settings&#039;&#039;&#039;&#039;&#039; öffnet sich das zweite Fenster, falls sich dieses nicht schon von alleine öffnen sollte. Nach den Schließen der Fenster über &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; ist der Projekt Dialog beendet und ein neues Projekt steht zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_5_1.png|Debug Eigenschaften 1. Fenster]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_5_2.png|Debug Eigenschaften 2. Fenster]]&lt;br /&gt;
&lt;br /&gt;
===2. CMSIS-Library und Startup-Code hinzufügen===&lt;br /&gt;
Wenn man sich, nachdem man ein neues Projekt in der IDE erstellt hat, die bereits vorhandenen Dateien im Projekt ansieht, stellt man fest, das bereits ein Ordner &#039;&#039;&#039;&#039;&#039;cmsis&#039;&#039;&#039;&#039;&#039; existiert, der einige wichtige Include-Dateien der CMSIS-Library enthält. Allerdings sind das wirklich nur die wichtigsten Include-Dateien der CMSIS-Library und dazu noch, die aus einer älternen Version. Ich ziehe es deshalb vor die &amp;quot;Mini-CMSIS-Libraray&amp;quot; und die &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c/.h&#039;&#039;&#039;&#039;&#039; Dateien des Projektes durch aktuellere Versionen zu ersetzen. So ist später auch die Integration  von anderen Libraries, wie z.B. der CMSIS-DSP-Libarary einfacher.  &lt;br /&gt;
&lt;br /&gt;
Zunächst gehen man in das Projekt-Verzeichnis und löscht:&lt;br /&gt;
*Den Ordner &#039;&#039;&#039;&#039;&#039;cmsis&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Alle Dateien im Include Verzeichnis &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; im &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner&lt;br /&gt;
&lt;br /&gt;
Außerdem entfernt man auch alle gelöschten Dateien in der IDE aus dem Projekt mit &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Rechts Klick -&amp;gt; Remove file from project&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Es sollte folgende Verzeichnis Struktur überbleiben:&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_6.png|Überbleibende Dateien]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Jetzt müssen die gelöschten Dateien durch die aktuelleren ersetzt werden.&lt;br /&gt;
&lt;br /&gt;
*Dazu kopieren man den gesamten Ordner &#039;&#039;&#039;&#039;&#039;CMSIS&#039;&#039;&#039;&#039;&#039; aus dem CMSIS Download in das Projekt Verzeichnis.&lt;br /&gt;
&lt;br /&gt;
*Aus dem Standard-Peripheral-Library Download kopiert man von &#039;&#039;&#039;&#039;&#039;Libraries\CMSIS\Device\ST\STM32F4xx\Include&#039;&#039;&#039;&#039;&#039; alle Dateien in den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projekt Verzeichnisses&lt;br /&gt;
&lt;br /&gt;
*Aus der Standard-Peripheral-Library kopieren man ebenfalls von &#039;&#039;&#039;&#039;&#039;Libraries\CMSIS\Device\ST\STM32F4xx\Source\Templates&#039;&#039;&#039;&#039;&#039; die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; in den &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner des Projekts&lt;br /&gt;
&lt;br /&gt;
Anschließend müssen die neuen Dateien in der IDE dem Projekt hinzugefügt werden. Dazu benutzt man &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Rechts Klick -&amp;gt; Add files&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
*Aus dem &#039;&#039;&#039;&#039;&#039;CMSIS&#039;&#039;&#039;&#039;&#039; Ordner im Projekt Verzeichnis werden aus den Unterorder &#039;&#039;&#039;&#039;&#039;Include&#039;&#039;&#039;&#039;&#039; folgende Dateien dem Projekt hinzugefügt:&lt;br /&gt;
**arm_common_tables.h&lt;br /&gt;
**arm_const_structs.h&lt;br /&gt;
**arm_math.h&lt;br /&gt;
**core_cm4.h&lt;br /&gt;
**core_cm4_simd.h&lt;br /&gt;
**core_cmFunc.h&lt;br /&gt;
**core_cmInstr.h&lt;br /&gt;
*Alle Dateien aus den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projektes&lt;br /&gt;
*Die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; aus dem &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner&lt;br /&gt;
&lt;br /&gt;
So sollte die Struktur dann aussehen:&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_7.png|Anwenungs-Grundgerüst]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Da einige Dateien der Libraries später bearbeitet werden müssen und Schreibgeschützt sind, weise ich hier schonmal darauf hin, das der Schreibschutz in der IDE über &#039;&#039;&#039;&#039;&#039;Rechts Klick auf die Datei -&amp;gt; Properties -&amp;gt; Häkchen bei &amp;quot;File is read only&amp;quot; entfernen&#039;&#039;&#039;&#039;&#039; entfert werden kann.&lt;br /&gt;
&lt;br /&gt;
Damit die IDE die Header-Dateien der CMSIS Library auch finden kann, weil diese ja nicht im standard Include Ordner &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; liegen, muss unter &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Build Options -&amp;gt; Search Directories&#039;&#039;&#039;&#039;&#039; der Pfad &#039;&#039;&#039;&#039;&#039;CMSIS\Include&#039;&#039;&#039;&#039;&#039; hinzugefügt werden.&lt;br /&gt;
&lt;br /&gt;
Compiliert man jetzt das Projekt mit &#039;&#039;&#039;&#039;&#039;F7&#039;&#039;&#039;&#039;&#039; gibt es ein paar Fehler Meldungen, weil keine Controller-Reihe ausgewählt wurde. Ebenfalls unter &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Build Options -&amp;gt; Compiler Settings -&amp;gt; #defines&#039;&#039;&#039;&#039;&#039; wird der Define &#039;&#039;&#039;&#039;&#039;STM32F40_41xxx&#039;&#039;&#039;&#039;&#039; hinzugefügt.&lt;br /&gt;
&lt;br /&gt;
Beim erneuten Compilieren sollten sich nun keine neuen Fehler ergeben.&lt;br /&gt;
&lt;br /&gt;
===Das erste Programm===&lt;br /&gt;
Nachdem ein grundsätzliches &amp;quot;Gerüst&amp;quot; fertig ist, kann man den ersten Code schreiben.&lt;br /&gt;
main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC-&amp;gt;AHB1ENR |= RCC_AHB1ENR_GPIODEN;    //Takt für GPIO aktivieren&lt;br /&gt;
    GPIOD-&amp;gt;MODER |= GPIO_MODER_MODER15_0;   //GPIOD Pin15 als Ausgang&lt;br /&gt;
    GPIOD-&amp;gt;BSRRL |= GPIO_BSRR_BS_15;        //GPIOD Pin15 auf High ziehen&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039; wird dann der Debugger gestartet. Hat der Debugger das Projekt erfolgreich übertragen kann die Ausführung mit &#039;&#039;&#039;&#039;&#039;F5&#039;&#039;&#039;&#039;&#039; begonnen werden.&lt;br /&gt;
&lt;br /&gt;
==Libraries einbinden/verwenden==&lt;br /&gt;
===Einbinden der Standard-Peripheral-Library===&lt;br /&gt;
Um nicht immer die einzelnen Register, wie im ersten &amp;quot;bare-metal&amp;quot; Beispiel, aus dem Reference-Manual zu suchen und zu beschreiben, gibt es von ST die Standard Peripheral Library, die diese Aufgaben übernimmt und mit der sich die &amp;quot;normale/grundlegende&amp;quot; (Alles außer USB und Ethernet) Peripherie recht einfach steuern lässt. Um die Library zu verwenden erzeugt man wie oben beschrieben ein neues Grundgerüst und kopiert als erstes den Ordner &#039;&#039;&#039;&#039;&#039;Libraries\STM32F4xx_StdPeriph_Driver&#039;&#039;&#039;&#039;&#039; aus dem Standard-Peripheral-Library Download in das Projekt-Verzeichnis. Außerdem muss man die Datei &#039;&#039;&#039;&#039;&#039;Project\STM32F4xx_StdPeriph_Templates\stm32f4xx_conf.h&#039;&#039;&#039;&#039;&#039; ebenfalls aus dem Standard-Peripheral-Library Download in den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projektes kopieren. In der IDE fügt man den Include-Path &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\inc&#039;&#039;&#039;&#039;&#039; hinzufügen, wie bei der CMSIS-Library (s.o.).&lt;br /&gt;
Außerdem muss noch &#039;&#039;&#039;&#039;&#039;USE_STDPERIPH_DRIVER&#039;&#039;&#039;&#039;&#039; als Define in der IDE hinzugefügt werden (s.o.).&lt;br /&gt;
Danach fügt man die Source- und Include-Dateien aus dem Ordner &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\inc&#039;&#039;&#039;&#039;&#039; und &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\src&#039;&#039;&#039;&#039;&#039; dem Project mit &#039;&#039;&#039;&#039;&#039;&amp;lt;Project Name&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Add files&#039;&#039;&#039;&#039;&#039; hinzu, allerdings nur die, für welche auch der Controller die entsprechende Peripherie besitzt. Beim STM32F4-Discovery Board / STM32F407VG Controller dürfen also nicht folgende Dateien nicht mit hinzugefügt werden, weil diese Peripherie nur bei anderen Controller vorhanden ist:&lt;br /&gt;
&lt;br /&gt;
*stm32f4xx_dma2d.c/.h&lt;br /&gt;
*stm32f4xx_fmc.c/.h&lt;br /&gt;
*stm32f4xx_ltdc.c/.h&lt;br /&gt;
*stm32f4xx_sai.c/.h&lt;br /&gt;
&lt;br /&gt;
Daraus resultiert folgende Struktur:&lt;br /&gt;
&lt;br /&gt;
[[Datei:stdperiphlib_2.png|Header-Struktur]] [[Datei:stdperiphlib_1.png|Source-Struktur]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Anschließen kann die Standard-Peripheral-Library benutz werden.&lt;br /&gt;
main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);&lt;br /&gt;
&lt;br /&gt;
    GPIO_InitTypeDef GPIOD_InitStructure;&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Mode = GPIO_Mode_OUT;     //Als Ausgang&lt;br /&gt;
    GPIOD_InitStructure.GPIO_OType = GPIO_OType_PP;    //Push-Pull Betrieb&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Pin = GPIO_Pin_15;        //Pin 15 (STM32F4-Discovery: Blaue LED)&lt;br /&gt;
    GPIOD_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;  //Kein Pull-Up oder Pull-Down Widerstand aktiviert&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Speed = GPIO_Speed_25MHz; //25MHz Update-Rate&lt;br /&gt;
    GPIO_Init(GPIOD, &amp;amp;GPIOD_InitStructure);&lt;br /&gt;
&lt;br /&gt;
    GPIO_SetBits(GPIOD, GPIO_Pin_15);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Startup-Code, Linkerscript, Takt, FPU usw.==&lt;br /&gt;
===Der Takt===&lt;br /&gt;
Jeder Controller oder Prozessor braucht einen Takt, indem er die einzelnen Maschinen-Befehle abarbeiten kann.&lt;br /&gt;
Bei den STM32 Mikrocontrollern kann dieser Takt aus verschiedenen Quellen kommen:&lt;br /&gt;
&lt;br /&gt;
1. High Speed Internal Oszillator (HSI)&lt;br /&gt;
&lt;br /&gt;
2. High Speed External Oszillator (HSE)&lt;br /&gt;
&lt;br /&gt;
3. Low Speed Internal Oszillator (LSI)&lt;br /&gt;
&lt;br /&gt;
4. Low Speed External Oszillator (LSE)&lt;br /&gt;
&lt;br /&gt;
5. Phase-Locked Loop (PLL) (generiert den Takt aus den ersten vier Taktquellen durch Teiler und Faktoren)&lt;br /&gt;
&lt;br /&gt;
Nach einem Reset wird der Controller aus der HSI Taktquelle versorgt (16MHz beim STM32F407VG). Um die voll Performance des Controllers zu erreichen muss die PLL verwendet werden, welche den Takt durch geschickte Teiler und Faktoren vervielfältigt, sodass am Ende der Controller mit der maximalen Taktfrequenz läuft. Die notwendige Initialisierung der PLL findet in der Funktion &#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; statt. Die PLL erzeugt zunächst einen Basistakt:&lt;br /&gt;
&lt;br /&gt;
PLL_VCO = (F_HSE / PLL_M) * PLL_N&lt;br /&gt;
&lt;br /&gt;
Aus diesem Takt wird dann der Takt für den Controller-Kern abgeleitet:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = PLL_VCO / PLL_P&lt;br /&gt;
&lt;br /&gt;
Und der Takt für SDIO / USB / RNG (48MHz):&lt;br /&gt;
&lt;br /&gt;
48MHz = PLL_VCO / PLL_Q&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Durch weiter Teiler werden, die Takte für die einzelnen Busse erzeugt, da diese nicht alle beliebig schnell betrieben werden dürfen.&lt;br /&gt;
&lt;br /&gt;
Genaue Angaben findet man zu dem jeweiligen Clock-System des Controllers im Reference Manual.&lt;br /&gt;
&lt;br /&gt;
Ein Blick in den &amp;quot;Kommentar-Header&amp;quot; verrät, dass von einem externen (HSE) Oszillator von 25MHz ausgegangen wird, der die PLL versorgen soll.&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((25MHz / PLL_M(25)) * PLL_N(336)) / PLL_P(2) = 168MHz&lt;br /&gt;
&lt;br /&gt;
Allerdings stimmt diese Rechnung natürlich nur, wenn wirklich ein 25MHz Quarz am Controller angeschlossen ist. Auf dem STM32F4-Discovery Board befindet sich aber nur ein 8MHz Quarz. Demnach gilt:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((8MHz / PLL_M(25)) * PLL_N(336)) / PLL_P(2) = 53.76MHz&lt;br /&gt;
&lt;br /&gt;
Der Controller läuft also nur mit 53.76MHz, wenn wie ober beschrieben ein Projekt erstellt wird. Allerdings kann dieses Problem durch ändern von den betroffen Defines behoben werden:&lt;br /&gt;
 &lt;br /&gt;
*Dazu geht man in die &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; Datei und passt zur Vollständigkeit erstmal die zum Controller passende Tabelle im &amp;quot;Kommentar-Header&amp;quot; an (Z.57f):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      HSE Frequency(Hz)                      | 8000000&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      PLL_M                                  | 8&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Danach passt man den PPL_M Define (Z.254) an:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/************************* PLL Parameters *************************************/&lt;br /&gt;
/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */&lt;br /&gt;
#define PLL_M      8&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Außerdem muss man den HSE_VALUE Define in der &#039;&#039;&#039;&#039;&#039;inc/stm32f4xx.h&#039;&#039;&#039;&#039;&#039; angepasst werden (Z.122):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#if !defined  (HSE_VALUE)&lt;br /&gt;
  #define HSE_VALUE    ((uint32_t)8000000) /*!&amp;lt; Value of the External oscillator in Hz */&lt;br /&gt;
&lt;br /&gt;
#endif /* HSE_VALUE */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine neue Berechnung zeigt:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((8MHz / PLL_M(8)) * PLL_N(336)) / PLL_P(2) = 168MHz&lt;br /&gt;
&lt;br /&gt;
Jetzt läuft der Controller mit maximaler Geschwindigkeit.&lt;br /&gt;
&lt;br /&gt;
Die Theorie wird durch folgendes Programm verifiziert. Der geviertelte System-Takt SYSCLK wir am Pin PC9 ausgegeben. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);&lt;br /&gt;
&lt;br /&gt;
    GPIO_InitTypeDef GPIOC_InitStructure;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Mode = GPIO_Mode_AF;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_OType = GPIO_OType_PP;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Pin = GPIO_Pin_9;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;&lt;br /&gt;
    GPIO_Init(GPIOC, &amp;amp;GPIOC_InitStructure);&lt;br /&gt;
&lt;br /&gt;
    RCC_MCO2Config(RCC_MCO2Source_SYSCLK, RCC_MCO2Div_4);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Die FPU===&lt;br /&gt;
====Allgemeines====&lt;br /&gt;
Damit die FPU richtig verwendet wird, müssen normalerweise zwei Bedingungen erfüllt sein:&lt;br /&gt;
&lt;br /&gt;
1. Der Controller muss in der Initialisierung-Funktion &#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; in &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; die FPU Hardware-seitig aktivieren&lt;br /&gt;
&lt;br /&gt;
2. Damit die FPU auch was zu tuen bekommt, müssen vom Compiler FPU-Instructions erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
Die Em::Blocks IDE verwendet standardmäßig die FPU, wenn eine Vorhanden ist. Hier wird die FPU Hardware-seitig aktiviert (&#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; Z.341):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* FPU settings ------------------------------------------------------------*/&lt;br /&gt;
  #if (__FPU_PRESENT == 1) &amp;amp;&amp;amp; (__FPU_USED == 1)&lt;br /&gt;
    SCB-&amp;gt;CPACR |= ((3UL &amp;lt;&amp;lt; 10*2)|(3UL &amp;lt;&amp;lt; 11*2));  /* set CP10 and CP11 Full Access */&lt;br /&gt;
  #endif&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
__FPU_PRESENT wird in der &#039;&#039;&#039;&#039;&#039;stm32f4xx.h&#039;&#039;&#039;&#039;&#039; definiert.&lt;br /&gt;
__FPU_USED wird von der IDE übernommen (siehe Build-Log): &#039;&#039;&#039;&#039;&#039;-D__FPU_USED&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Außerdem wird der Compiler von der IDE standardmäßig mit dem Argument &#039;&#039;&#039;&#039;&#039;-mfloat-abi=hard&#039;&#039;&#039;&#039;&#039; aufgerufen, wodurch FPU-Instructions erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
====FPU abschalten====&lt;br /&gt;
Um die FPU ab zu schalten (Mir würde jetzt nur Strom sparen als Grund einfallen) geht man wie folgt vor:&lt;br /&gt;
&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick Build options -&amp;gt; Device -&amp;gt; Policy&#039;&#039;&#039;&#039;&#039; wählt man &#039;&#039;&#039;&#039;&#039;Use target settings&#039;&#039;&#039;&#039;&#039; und über nimmt die Einstellungen, die vorher dort eingetragen waren, allerdings lässt man das Feld &#039;&#039;&#039;&#039;&#039;FP-hardware&#039;&#039;&#039;&#039;&#039; frei.&lt;br /&gt;
&lt;br /&gt;
[[Datei:fpu_1.png|FPU Abschalten Schritt 1]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;Compiler Settings -&amp;gt; Policy&#039;&#039;&#039;&#039;&#039; wählt man dann &#039;&#039;&#039;&#039;&#039;Use target options only&#039;&#039;&#039;&#039;&#039;. Dann kann man unter &#039;&#039;&#039;&#039;&#039;Categories&#039;&#039;&#039;&#039;&#039; die Option &#039;&#039;&#039;&#039;&#039;ARM FPU architecture&#039;&#039;&#039;&#039;&#039; auswählen. Dort stehen dann drei Möglichkeiten für die FPU zur Verfügung:&lt;br /&gt;
&lt;br /&gt;
1. Software-FPU-Library für Gleitkomma-Berechnung verwenden - Keine FPU-Instructions werden generiert (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=soft&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
2. Eine Mischung aus Software- und Hardware-FPU wird verwendet (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=softfp&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
3. Hardware-FPU wird für Gleitkomma-Berechnungen verwendet (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=hard&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
[[Datei:fpu_2.png|FPU Abschalten Schritt 2]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Um die FPU ab zu schalten wählt man natürlich die erste Möglichkeit.&lt;br /&gt;
Bei der 2. und 3. Möglichkeit fügt die IDE auch den Define &#039;&#039;&#039;&#039;&#039;__FPU_USED&#039;&#039;&#039;&#039;&#039; hinzu. Bei Der ersten Möglichkeit nicht. Der Code muss also nicht verändert / auskommentiert werden.&lt;br /&gt;
&lt;br /&gt;
Um die FPU wieder zu aktivieren müssen alle Schritte wieder rückgängig gemacht werden.&lt;br /&gt;
&lt;br /&gt;
Am besten ist es einfach mal alle Möglichkeiten im Einzelschritt durch zu probieren. Dann stellt man schnell fest, ob die FPU aktiviert wir oder nicht. Ein Blick in den erweiterten &#039;&#039;&#039;&#039;&#039;Build-Log&#039;&#039;&#039;&#039;&#039; gibt auch schnell Aufschluss darüber, wie der Compiler aufgerufen wird (siehe Kapitel [http://www.mikrocontroller.net/articles/STM32_-_Einstieg_mit_Em::Blocks#Compilieren Compilieren]).&lt;br /&gt;
&lt;br /&gt;
====Test Programm für die FPU====&lt;br /&gt;
Hier ein kleines Testprogramm, dass misst wie viele Taktzyklen für eine Gleitkomma-Multiplikation gebraucht werden. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define CORE_SysTickEn()    (*((u32*)0xE0001000)) = 0x40000001&lt;br /&gt;
#define CORE_SysTickDis()   (*((u32*)0xE0001000)) = 0x40000000&lt;br /&gt;
#define CORE_GetSysTick()   (*((u32*)0xE0001004))&lt;br /&gt;
&lt;br /&gt;
uint32_t t1, t2, dt;&lt;br /&gt;
float x, y, z;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    x = 53.64f;&lt;br /&gt;
    y = 0.27f;&lt;br /&gt;
&lt;br /&gt;
    CORE_SysTickEn();&lt;br /&gt;
    t1 = CORE_GetSysTick();&lt;br /&gt;
&lt;br /&gt;
    z = x * y;&lt;br /&gt;
&lt;br /&gt;
    t2 = CORE_GetSysTick();&lt;br /&gt;
    CORE_SysTickDis();&lt;br /&gt;
&lt;br /&gt;
    dt = t2 - t1;&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mein Ergebnis:&lt;br /&gt;
*Mit Hardware-FPU:  dt = 25&lt;br /&gt;
*Ohne Hardware-FPU: dt = 83&lt;br /&gt;
&lt;br /&gt;
==Booten aus dem SRAM==&lt;br /&gt;
STM32 Controller haben die Möglichkeit Code aus dem Flash als auch aus dem SRAM auszuführen. Um eine Anwenung per Debugger in des SRAM zu laden sind nur wenige Schritte erforderlich:&lt;br /&gt;
&lt;br /&gt;
*Um das Linkerscript für den SRAM zu verwenden geht man zu: &#039;&#039;&#039;&#039;&#039;Build options... -&amp;gt; Device&#039;&#039;&#039;&#039;&#039; dort wählt man unter &#039;&#039;&#039;&#039;&#039;Policy&#039;&#039;&#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;Use target settings&#039;&#039;&#039;&#039;&#039; aus und übernimmt die vorherigen Einstellungen, nur unter &#039;&#039;&#039;&#039;&#039;Linker script*&#039;&#039;&#039;&#039;&#039; gibt man &#039;&#039;&#039;&#039;&#039;.\stm32f407vg_sram.ld&#039;&#039;&#039;&#039;&#039; an&lt;br /&gt;
&lt;br /&gt;
*Dann muss man noch unter &#039;&#039;&#039;&#039;&#039;Debug -&amp;gt; Interfaces -&amp;gt; Settings&#039;&#039;&#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;Vector table start&#039;&#039;&#039;&#039;&#039; auf 0x20000000 ändern und &#039;&#039;&#039;&#039;&#039;Execute from RAM&#039;&#039;&#039;&#039;&#039; auswählen.&lt;br /&gt;
&lt;br /&gt;
Anschließend kann man die Anwendung ganz normal debuggen. Nach einem Reset muss die Anwenung erneut mit dem Debugger gestartet werden.&lt;br /&gt;
&lt;br /&gt;
=Fortsetzung folgt..=&lt;br /&gt;
Kritik, Wünsche usw. sind gerne erwünscht, am besten hier in den Thread posten: [http://www.mikrocontroller.net/topic/323750 Neues STM32 Tutorial]&lt;br /&gt;
&lt;br /&gt;
[[Category:ARM]]&lt;br /&gt;
[[Category:STM32]]&lt;/div&gt;</summary>
		<author><name>Avrprogger</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=STM32_-_Einstieg_mit_Em::Blocks&amp;diff=81505</id>
		<title>STM32 - Einstieg mit Em::Blocks</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=STM32_-_Einstieg_mit_Em::Blocks&amp;diff=81505"/>
		<updated>2014-02-10T15:25:39Z</updated>

		<summary type="html">&lt;p&gt;Avrprogger: bnm&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In diesem Tutorial werde ich versuchen, möglichst einfach, die ersten Schritte zur Entwicklung von STM32 Anwenungen mit der Em::Blocks IDE zu erklären. Hier soll nicht so stark auf die einzelnen Peripherie-Module der Controller eingegangen werden, sondern mehr auf die IDE und die verschieden Libraries, wie die CMSIS Library, die DSP-Library, die Standard-Peripheral-Library, die USB-Library und vllt. über Ethernet. Ich denke ein Kapitel zu FreeRTOS wird es auch geben. Auserdem steht im Vordergrund Sachen wie z.B. booten aus dem SRAM, In-Application-Programming, FPU, Core-Coupled-RAM usw. Mal sehn wie weit ich komme ;)&lt;br /&gt;
&lt;br /&gt;
==Die Entwicklungsumgebung==&lt;br /&gt;
===Hardware===&lt;br /&gt;
Zum testen der Anwendungen, benutze ich das STM32F4-Discovery Board, welches einen Debugger, Peripherie und natürlich einen STM32 Controller (STM32F407VGT6) enthält. Deshalb sind alle Beispiele hier für den STM32F407VG Controller ausgelegt, können aber meisten 1:1 auf andere Controller portiert werden. Ich werde auch möglichsts keine STM32F4-Discovery Board spezifischen Libraries verwenden, damit der Portierungs-Vorgang möglichsts einfach bleibt.&lt;br /&gt;
&lt;br /&gt;
===Software===&lt;br /&gt;
In diesem Tutorial verwende ich [http://www.emblocks.org/ Em::Blocks] als IDE. Em::Blocks ist eine kostenlose, uneingeschränkte IDE, die alle STM32 Mikrcontroller unterstützt und sehr einfach zu bedienen ist.&lt;br /&gt;
nach dem Download kann die IDE per Dialog, sehr einfach, installiert werden. Als Compiler beinhaltet Em::Blocks den &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
Die IDE unterstützt zurzeit den ST-Link, den J-Link und es gibt eine Generic-Vorlage, durch welche andere Debugger konfiguriert werden können.&lt;br /&gt;
&lt;br /&gt;
Außerdem muss noch der passende Treiber für den Debugger installiert werden. Verwendet man ein Discovery-Board muss der [http://www.st.com/web/catalog/tools/FM146/CL1984/SC724/SS1677/PF251168 ST-Link/V2]-Treiber heruntergeladen und installiert werden. (Die Installation muss evtl. als Administrator ausgeführt werden, da sonst die Installation unvollständig wird.) Nach der Installation des Treibers kann man den Debugger über die entsprechende USB Schnittstelle an den PC anschließen und es sollte die Meldung von Windows kommen, dass der richtige Treiber gefunden wurde.&lt;br /&gt;
&lt;br /&gt;
===Libraries===&lt;br /&gt;
Zum programmieren benötigt man noch die [http://www.arm.com/products/processors/cortex-m/cortex-microcontroller-software-interface-standard.php CMSIS] und die Standard-Peripheral-Library (z.B. für die F4 Controller [http://www.st.com/stonline/stappl/productcatalog/app?page=partNumberSearchPage&amp;amp;levelid=SS1577&amp;amp;parentid=1743&amp;amp;resourcetype=SW Standard-Peripheral-Library-F4]), die man am besten in einen Ordner (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\STM32&#039;&#039;&#039;&#039;&#039;) entpackt&lt;br /&gt;
&lt;br /&gt;
==Basis-Wissen zur IDE==&lt;br /&gt;
Einige Grundfunktionalitäten der IDE:&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von Dateien zum Projekt===&lt;br /&gt;
Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf &amp;lt;ProjektName&amp;gt; -&amp;gt; Add files...&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Enfernen von Dateien aus dem Projekt===&lt;br /&gt;
Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf die Datei / mehrere Dateien auswählen -&amp;gt; Remove file from project&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
Die Dateien werden lediglich aus dem Projekt entfernt und nicht von der Festplatte gelöscht.&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von Include-Pfaden===&lt;br /&gt;
Sofern die Include-Datei(en) nicht im standard Include-Ordner &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; des Projektes liegen, muss man den Pfad zum Projekt hinzufügen, damit der Compiler die Include-Dateien später auch finden kann. Man geht wie folgt vor: Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf &amp;lt;ProjektName&amp;gt; -&amp;gt; Build options... -&amp;gt; Search Directories -&amp;gt; Add&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Compilieren===&lt;br /&gt;
Entweder über das &#039;&#039;&#039;&#039;&#039;Build&#039;&#039;&#039;&#039;&#039; Menü oder über &#039;&#039;&#039;&#039;&#039;F7&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Um eine genau Ausgabe des Compiler-Aufrufes mit allen Argumenten zu bekommen, geht man im &#039;&#039;&#039;&#039;&#039;Settings&#039;&#039;&#039;&#039;&#039; Menü auf &#039;&#039;&#039;&#039;&#039;Tools...&#039;&#039;&#039;&#039;&#039; und dann auf &#039;&#039;&#039;&#039;&#039;Toolchain executables&#039;&#039;&#039;&#039;&#039;. Ganz unten, unter &#039;&#039;&#039;&#039;&#039;Logging&#039;&#039;&#039;&#039;&#039; kann man dann &#039;&#039;&#039;&#039;&#039;Full command line&#039;&#039;&#039;&#039;&#039; auswählen.&lt;br /&gt;
&lt;br /&gt;
===Debuggen===&lt;br /&gt;
*Als erstes den Debugger starten über das &#039;&#039;&#039;&#039;&#039;Debug&#039;&#039;&#039;&#039;&#039; Menü und &#039;&#039;&#039;&#039;&#039;Start/stop Debug Session&#039;&#039;&#039;&#039;&#039; oder über &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
*Danach läuft die Anwendung auf dem Controller und warten im &#039;&#039;&#039;&#039;&#039;Reset_Handler&#039;&#039;&#039;&#039;&#039; auf Einzelschritt- bzw. Run- Befehle (&#039;&#039;&#039;&#039;&#039;F5, F10, F11&#039;&#039;&#039;&#039;&#039; usw..(siehe &#039;&#039;&#039;&#039;&#039;Debug-Menü&#039;&#039;&#039;&#039;&#039; für alle Möglichkeiten))&lt;br /&gt;
&lt;br /&gt;
*Mit &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039; wird die Debug-Session auch wieder beendet&lt;br /&gt;
&lt;br /&gt;
*Unter &#039;&#039;&#039;&#039;&#039;Debug -&amp;gt; Interfaces -&amp;gt; Target settings&#039;&#039;&#039;&#039;&#039; können Eigenschaften, wie z.B &#039;&#039;&#039;&#039;&#039;Run to main()&#039;&#039;&#039;&#039;&#039; aktiviert werden.&lt;br /&gt;
&lt;br /&gt;
===Projekt als Template abspeichern===&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;File -&amp;gt; Save project as template...&#039;&#039;&#039;&#039;&#039;. Das Template erscheint dann im Projekt-Dialog unter &#039;&#039;&#039;&#039;&#039;User templates&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Das erste Projekt erstellen==&lt;br /&gt;
Hier erkläre ich, wie man am Besten (aus meiner Sicht), ein neues Projekt von Grund auf erstellt, sodass man hinterher, den Controller-Kern über die CMSIS-Library und die Peripherie über die Register steuern kann.&lt;br /&gt;
&lt;br /&gt;
===1. Projekt mit der IDE erstellen===&lt;br /&gt;
Nach der Installation der oben beschriebenen Komponenten erstellt man am besten ein Verzeichnis (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\EmBlocks&#039;&#039;&#039;&#039;&#039;), indem später alle Projekte gespeichert werden. Für Libraries kann man auch noch ein Verzeichnis (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\STM32&#039;&#039;&#039;&#039;&#039;) erstellen, wo alle Libraries gespeichert werden, die man für die Projekt brauchen.&lt;br /&gt;
&lt;br /&gt;
Als nächstes starten man EmBlocks. Bei dem ersten Start öffnet sich ein Fenster, wo verschiedene Compiler angezeigt werden, die Em::Blocks findet. Dort wählt man den &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039; aus und klickt &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039;. Nun sollte sich das Hauptfenster von Em::Blocks öffnen. Über &#039;&#039;&#039;&#039;&#039;Create a new Project&#039;&#039;&#039;&#039;&#039; oder &#039;&#039;&#039;&#039;&#039;File -&amp;gt; New -&amp;gt; Project&#039;&#039;&#039;&#039;&#039; ruft man den Projekt-Dialog auf und kann ein neues Projekt erzeugen.&lt;br /&gt;
&lt;br /&gt;
Auf der Ersten Seite wählen man den &#039;&#039;&#039;&#039;&#039;STmicro-ARM&#039;&#039;&#039;&#039;&#039; Projekt-Typ aus.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_1.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auf der nächsten Seite wird man darauf hingewiesen, dass das der entsprechende Projekt-Typ-Dialog ausgeführt wird. Hier kann man ein Häkchen bei &#039;&#039;&#039;&#039;&#039;Skip this page next time&#039;&#039;&#039;&#039;&#039; setzen und auf &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; klicken.&lt;br /&gt;
&lt;br /&gt;
Im nächsten Schritt wählen man das zuvor erstellt Verzeichnis unter &#039;&#039;&#039;&#039;&#039;Folder to create Project in&#039;&#039;&#039;&#039;&#039; aus, indem später alle Projekt gespeichert werden. Außerdem geben wir dem Projekt einen Namen (z.B. &#039;&#039;&#039;&#039;&#039;FirstProject&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_2.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danach muss man einen Compiler auswählen und bestimmen, welche Projekt-Konfigurationen erszeugt werden sollen. Unter &#039;&#039;&#039;&#039;&#039;Compiler&#039;&#039;&#039;&#039;&#039; wählt man &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039; und man kann das Häkchen bei &#039;&#039;&#039;&#039;&#039;Create &amp;quot;Release&amp;quot; configuration&#039;&#039;&#039;&#039;&#039; entfernen, da diese unnötig ist, die Debug-Konfiguration sollte eig. immer ausreichen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_3.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auf den folgenden Seite wird der Controller ausgewählt. Verwendet man ein STM32F4-Discovery Board müssen folgende Dinge gewählt werden: &#039;&#039;&#039;&#039;&#039;Cortex_M4 (F3xx - F4xx) -&amp;gt; STM32F4xx (Cortex M4 with FPU) -&amp;gt; STM32F407VG&#039;&#039;&#039;&#039;&#039;. Leider sind die Auswahl Möglichkeiten nicht ganz richtig, da auch die F3 Controller einen Cortex M4 Kern und eine FPU haben (Ist aber nicht so wichtig, ist nur eine formale Sache). Außerdem entfernt man das Häkchen bei &#039;&#039;&#039;&#039;&#039;Standard Peripherals Library&#039;&#039;&#039;&#039;&#039; (Wie man die Standard-Peripheral-Library einbindet und verwendet erkläre ich später). Man kann auch das Häkchen bei &#039;&#039;&#039;&#039;&#039;Create hex file for Realease target&#039;&#039;&#039;&#039;&#039; entfernen.&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;Stack Size&#039;&#039;&#039;&#039;&#039; und &#039;&#039;&#039;&#039;&#039;Heap Size&#039;&#039;&#039;&#039;&#039; wird die Größe von Stack und Heap festgelegt. Für eine erste Anwendung kann man die Einstellungen so lassen (Stack-Size: 0x0100 =&amp;gt; 256 Byte Stack und Heap-Size: 0x0000 =&amp;gt; kein Heap). Mit &#039;&#039;&#039;&#039;&#039;Finish&#039;&#039;&#039;&#039;&#039; ist der Projekt Dialog abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_4.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danach sollten sich zwei neue Fenster öffnen, um die Debug-Eigenschaften fest zu legen.&lt;br /&gt;
Verwendet man ein Discovery Board/ST-Link müssen die Einstellungen wie auf dem Bild gewählt werden. Über den Button &#039;&#039;&#039;&#039;&#039;Settings&#039;&#039;&#039;&#039;&#039; öffnet sich das zweite Fenster, falls sich dieses nicht schon von alleine öffnen sollte. Nach den Schließen der Fenster über &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; ist der Projekt Dialog beendet und ein neues Projekt steht zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_5_1.png|Debug Eigenschaften 1. Fenster]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_5_2.png|Debug Eigenschaften 2. Fenster]]&lt;br /&gt;
&lt;br /&gt;
===2. CMSIS-Library und Startup-Code hinzufügen===&lt;br /&gt;
Wenn man sich, nachdem man ein neues Projekt in der IDE erstellt hat, die bereits vorhandenen Dateien im Projekt ansieht, stellt man fest, das bereits ein Ordner &#039;&#039;&#039;&#039;&#039;cmsis&#039;&#039;&#039;&#039;&#039; existiert, der einige wichtige Include-Dateien der CMSIS-Library enthält. Allerdings sind das wirklich nur die wichtigsten Include-Dateien der CMSIS-Library und dazu noch, die aus einer älternen Version. Ich ziehe es deshalb vor die &amp;quot;Mini-CMSIS-Libraray&amp;quot; und die &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c/.h&#039;&#039;&#039;&#039;&#039; Dateien des Projektes durch aktuellere Versionen zu ersetzen. So ist später auch die Integration  von anderen Libraries, wie z.B. der CMSIS-DSP-Libarary einfacher.  &lt;br /&gt;
&lt;br /&gt;
Zunächst gehen man in das Projekt-Verzeichnis und löscht:&lt;br /&gt;
*Den Ordner &#039;&#039;&#039;&#039;&#039;cmsis&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Alle Dateien im Include Verzeichnis &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; im &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner&lt;br /&gt;
&lt;br /&gt;
Außerdem entfernt man auch alle gelöschten Dateien in der IDE aus dem Projekt mit &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Rechts Klick -&amp;gt; Remove file from project&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Es sollte folgende Verzeichnis Struktur überbleiben:&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_6.png|Überbleibende Dateien]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Jetzt müssen die gelöschten Dateien durch die aktuelleren ersetzt werden.&lt;br /&gt;
&lt;br /&gt;
*Dazu kopieren man den gesamten Ordner &#039;&#039;&#039;&#039;&#039;CMSIS&#039;&#039;&#039;&#039;&#039; aus dem CMSIS Download in das Projekt Verzeichnis.&lt;br /&gt;
&lt;br /&gt;
*Aus dem Standard-Peripheral-Library Download kopiert man von &#039;&#039;&#039;&#039;&#039;Libraries\CMSIS\Device\ST\STM32F4xx\Include&#039;&#039;&#039;&#039;&#039; alle Dateien in den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projekt Verzeichnisses&lt;br /&gt;
&lt;br /&gt;
*Aus der Standard-Peripheral-Library kopieren man ebenfalls von &#039;&#039;&#039;&#039;&#039;Libraries\CMSIS\Device\ST\STM32F4xx\Source\Templates&#039;&#039;&#039;&#039;&#039; die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; in den &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner des Projekts&lt;br /&gt;
&lt;br /&gt;
Anschließend müssen die neuen Dateien in der IDE dem Projekt hinzugefügt werden. Dazu benutzt man &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Rechts Klick -&amp;gt; Add files&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
*Aus dem &#039;&#039;&#039;&#039;&#039;CMSIS&#039;&#039;&#039;&#039;&#039; Ordner im Projekt Verzeichnis werden aus den Unterorder &#039;&#039;&#039;&#039;&#039;Include&#039;&#039;&#039;&#039;&#039; folgende Dateien dem Projekt hinzugefügt:&lt;br /&gt;
**arm_common_tables.h&lt;br /&gt;
**arm_const_structs.h&lt;br /&gt;
**arm_math.h&lt;br /&gt;
**core_cm4.h&lt;br /&gt;
**core_cm4_simd.h&lt;br /&gt;
**core_cmFunc.h&lt;br /&gt;
**core_cmInstr.h&lt;br /&gt;
*Alle Dateien aus den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projektes&lt;br /&gt;
*Die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; aus dem &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner&lt;br /&gt;
&lt;br /&gt;
So sollte die Struktur dann aussehen:&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_7.png|Anwenungs-Grundgerüst]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Da einige Dateien der Libraries später bearbeitet werden müssen und Schreibgeschützt sind, weise ich hier schonmal darauf hin, das der Schreibschutz in der IDE über &#039;&#039;&#039;&#039;&#039;Rechts Klick auf die Datei -&amp;gt; Properties -&amp;gt; Häkchen bei &amp;quot;File is read only&amp;quot; entfernen&#039;&#039;&#039;&#039;&#039; entfert werden kann.&lt;br /&gt;
&lt;br /&gt;
Damit die IDE die Header-Dateien der CMSIS Library auch finden kann, weil diese ja nicht im standard Include Ordner &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; liegen, muss unter &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Build Options -&amp;gt; Search Directories&#039;&#039;&#039;&#039;&#039; der Pfad &#039;&#039;&#039;&#039;&#039;CMSIS\Include&#039;&#039;&#039;&#039;&#039; hinzugefügt werden.&lt;br /&gt;
&lt;br /&gt;
Compiliert man jetzt das Projekt mit &#039;&#039;&#039;&#039;&#039;F7&#039;&#039;&#039;&#039;&#039; gibt es ein paar Fehler Meldungen, weil keine Controller-Reihe ausgewählt wurde. Ebenfalls unter &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Build Options -&amp;gt; Compiler Settings -&amp;gt; #defines&#039;&#039;&#039;&#039;&#039; wird der Define &#039;&#039;&#039;&#039;&#039;STM32F40_41xxx&#039;&#039;&#039;&#039;&#039; hinzugefügt.&lt;br /&gt;
&lt;br /&gt;
Beim erneuten Compilieren sollten sich nun keine neuen Fehler ergeben.&lt;br /&gt;
&lt;br /&gt;
===Das erste Programm===&lt;br /&gt;
Nachdem ein grundsätzliches &amp;quot;Gerüst&amp;quot; fertig ist, kann man den ersten Code schreiben.&lt;br /&gt;
main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC-&amp;gt;AHB1ENR |= RCC_AHB1ENR_GPIODEN;    //Takt für GPIO aktivieren&lt;br /&gt;
    GPIOD-&amp;gt;MODER |= GPIO_MODER_MODER15_0;   //GPIOD Pin15 als Ausgang&lt;br /&gt;
    GPIOD-&amp;gt;BSRRL |= GPIO_BSRR_BS_15;        //GPIOD Pin15 auf High ziehen&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039; wird dann der Debugger gestartet. Hat der Debugger das Projekt erfolgreich übertragen kann die Ausführung mit &#039;&#039;&#039;&#039;&#039;F5&#039;&#039;&#039;&#039;&#039; begonnen werden.&lt;br /&gt;
&lt;br /&gt;
==Libraries einbinden/verwenden==&lt;br /&gt;
===Einbinden der Standard-Peripheral-Library===&lt;br /&gt;
Um nicht immer die einzelnen Register, wie im ersten &amp;quot;bare-metal&amp;quot; Beispiel, aus dem Reference-Manual zu suchen und zu beschreiben, gibt es von ST die Standard Peripheral Library, die diese Aufgaben übernimmt und mit der sich die &amp;quot;normale/grundlegende&amp;quot; (Alles außer USB und Ethernet) Peripherie recht einfach steuern lässt. Um die Library zu verwenden erzeugt man wie oben beschrieben ein neues Grundgerüst und kopiert als erstes den Ordner &#039;&#039;&#039;&#039;&#039;Libraries\STM32F4xx_StdPeriph_Driver&#039;&#039;&#039;&#039;&#039; aus dem Standard-Peripheral-Library Download in das Projekt-Verzeichnis. Außerdem muss man die Datei &#039;&#039;&#039;&#039;&#039;Project\STM32F4xx_StdPeriph_Templates\stm32f4xx_conf.h&#039;&#039;&#039;&#039;&#039; ebenfalls aus dem Standard-Peripheral-Library Download in den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projektes kopieren. In der IDE fügt man den Include-Path &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\inc&#039;&#039;&#039;&#039;&#039; hinzufügen, wie bei der CMSIS-Library (s.o.).&lt;br /&gt;
Außerdem muss noch &#039;&#039;&#039;&#039;&#039;USE_STDPERIPH_DRIVER&#039;&#039;&#039;&#039;&#039; als Define in der IDE hinzugefügt werden (s.o.).&lt;br /&gt;
Danach fügt man die Source- und Include-Dateien aus dem Ordner &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\inc&#039;&#039;&#039;&#039;&#039; und &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\src&#039;&#039;&#039;&#039;&#039; dem Project mit &#039;&#039;&#039;&#039;&#039;&amp;lt;Project Name&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Add files&#039;&#039;&#039;&#039;&#039; hinzu, allerdings nur die, für welche auch der Controller die entsprechende Peripherie besitzt. Beim STM32F4-Discovery Board / STM32F407VG Controller dürfen also nicht folgende Dateien nicht mit hinzugefügt werden, weil diese Peripherie nur bei anderen Controller vorhanden ist:&lt;br /&gt;
&lt;br /&gt;
*stm32f4xx_dma2d.c/.h&lt;br /&gt;
*stm32f4xx_fmc.c/.h&lt;br /&gt;
*stm32f4xx_ltdc.c/.h&lt;br /&gt;
*stm32f4xx_sai.c/.h&lt;br /&gt;
&lt;br /&gt;
Daraus resultiert folgende Struktur:&lt;br /&gt;
&lt;br /&gt;
[[Datei:stdperiphlib_2.png|Header-Struktur]] [[Datei:stdperiphlib_1.png|Source-Struktur]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Anschließen kann die Standard-Peripheral-Library benutz werden.&lt;br /&gt;
main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);&lt;br /&gt;
&lt;br /&gt;
    GPIO_InitTypeDef GPIOD_InitStructure;&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Mode = GPIO_Mode_OUT;     //Als Ausgang&lt;br /&gt;
    GPIOD_InitStructure.GPIO_OType = GPIO_OType_PP;    //Push-Pull Betrieb&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Pin = GPIO_Pin_15;        //Pin 15 (STM32F4-Discovery: Blaue LED)&lt;br /&gt;
    GPIOD_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;  //Kein Pull-Up oder Pull-Down Widerstand aktiviert&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Speed = GPIO_Speed_25MHz; //25MHz Update-Rate&lt;br /&gt;
    GPIO_Init(GPIOD, &amp;amp;GPIOD_InitStructure);&lt;br /&gt;
&lt;br /&gt;
    GPIO_SetBits(GPIOD, GPIO_Pin_15);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Takt, FPU usw.==&lt;br /&gt;
===Der Takt===&lt;br /&gt;
Jeder Controller oder Prozessor braucht einen Takt, indem er die einzelnen Maschinen-Befehle abarbeiten kann.&lt;br /&gt;
Bei den STM32 Mikrocontrollern kann dieser Takt aus verschiedenen Quellen kommen:&lt;br /&gt;
&lt;br /&gt;
1. High Speed Internal Oszillator (HSI)&lt;br /&gt;
&lt;br /&gt;
2. High Speed External Oszillator (HSE)&lt;br /&gt;
&lt;br /&gt;
3. Low Speed Internal Oszillator (LSI)&lt;br /&gt;
&lt;br /&gt;
4. Low Speed External Oszillator (LSE)&lt;br /&gt;
&lt;br /&gt;
5. Phase-Locked Loop (PLL) (generiert den Takt aus den ersten vier Taktquellen durch Teiler und Faktoren)&lt;br /&gt;
&lt;br /&gt;
Nach einem Reset wird der Controller aus der HSI Taktquelle versorgt (16MHz beim STM32F407VG). Um die voll Performance des Controllers zu erreichen muss die PLL verwendet werden, welche den Takt durch geschickte Teiler und Faktoren vervielfältigt, sodass am Ende der Controller mit der maximalen Taktfrequenz läuft. Die notwendige Initialisierung der PLL findet in der Funktion &#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; statt. Die PLL erzeugt zunächst einen Basistakt:&lt;br /&gt;
&lt;br /&gt;
PLL_VCO = (F_HSE / PLL_M) * PLL_N&lt;br /&gt;
&lt;br /&gt;
Aus diesem Takt wird dann der Takt für den Controller-Kern abgeleitet:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = PLL_VCO / PLL_P&lt;br /&gt;
&lt;br /&gt;
Und der Takt für SDIO / USB / RNG (48MHz):&lt;br /&gt;
&lt;br /&gt;
48MHz = PLL_VCO / PLL_Q&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Durch weiter Teiler werden, die Takte für die einzelnen Busse erzeugt, da diese nicht alle beliebig schnell betrieben werden dürfen.&lt;br /&gt;
&lt;br /&gt;
Genaue Angaben findet man zu dem jeweiligen Clock-System des Controllers im Reference Manual.&lt;br /&gt;
&lt;br /&gt;
Ein Blick in den &amp;quot;Kommentar-Header&amp;quot; verrät, dass von einem externen (HSE) Oszillator von 25MHz ausgegangen wird, der die PLL versorgen soll.&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((25MHz / PLL_M(25)) * PLL_N(336)) / PLL_P(2) = 168MHz&lt;br /&gt;
&lt;br /&gt;
Allerdings stimmt diese Rechnung natürlich nur, wenn wirklich ein 25MHz Quarz am Controller angeschlossen ist. Auf dem STM32F4-Discovery Board befindet sich aber nur ein 8MHz Quarz. Demnach gilt:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((8MHz / PLL_M(25)) * PLL_N(336)) / PLL_P(2) = 53.76MHz&lt;br /&gt;
&lt;br /&gt;
Der Controller läuft also nur mit 53.76MHz, wenn wie ober beschrieben ein Projekt erstellt wird. Allerdings kann dieses Problem durch ändern von den betroffen Defines behoben werden:&lt;br /&gt;
 &lt;br /&gt;
*Dazu geht man in die &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; Datei und passt zur Vollständigkeit erstmal die zum Controller passende Tabelle im &amp;quot;Kommentar-Header&amp;quot; an (Z.57f):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      HSE Frequency(Hz)                      | 8000000&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      PLL_M                                  | 8&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Danach passt man den PPL_M Define (Z.254) an:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/************************* PLL Parameters *************************************/&lt;br /&gt;
/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */&lt;br /&gt;
#define PLL_M      8&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Außerdem muss man den HSE_VALUE Define in der &#039;&#039;&#039;&#039;&#039;inc/stm32f4xx.h&#039;&#039;&#039;&#039;&#039; angepasst werden (Z.122):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#if !defined  (HSE_VALUE)&lt;br /&gt;
  #define HSE_VALUE    ((uint32_t)8000000) /*!&amp;lt; Value of the External oscillator in Hz */&lt;br /&gt;
&lt;br /&gt;
#endif /* HSE_VALUE */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine neue Berechnung zeigt:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((8MHz / PLL_M(8)) * PLL_N(336)) / PLL_P(2) = 168MHz&lt;br /&gt;
&lt;br /&gt;
Jetzt läuft der Controller mit maximaler Geschwindigkeit.&lt;br /&gt;
&lt;br /&gt;
Die Theorie wird durch folgendes Programm verifiziert. Der geviertelte System-Takt SYSCLK wir am Pin PC9 ausgegeben. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);&lt;br /&gt;
&lt;br /&gt;
    GPIO_InitTypeDef GPIOC_InitStructure;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Mode = GPIO_Mode_AF;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_OType = GPIO_OType_PP;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Pin = GPIO_Pin_9;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;&lt;br /&gt;
    GPIO_Init(GPIOC, &amp;amp;GPIOC_InitStructure);&lt;br /&gt;
&lt;br /&gt;
    RCC_MCO2Config(RCC_MCO2Source_SYSCLK, RCC_MCO2Div_4);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Die FPU===&lt;br /&gt;
====Allgemeines====&lt;br /&gt;
Damit die FPU richtig verwendet wird, müssen normalerweise zwei Bedingungen erfüllt sein:&lt;br /&gt;
&lt;br /&gt;
1. Der Controller muss in der Initialisierung-Funktion &#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; in &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; die FPU Hardware-seitig aktivieren&lt;br /&gt;
&lt;br /&gt;
2. Damit die FPU auch was zu tuen bekommt, müssen vom Compiler FPU-Instructions erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
Die Em::Blocks IDE verwendet standardmäßig die FPU, wenn eine Vorhanden ist. Hier wird die FPU Hardware-seitig aktiviert (&#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; Z.341):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* FPU settings ------------------------------------------------------------*/&lt;br /&gt;
  #if (__FPU_PRESENT == 1) &amp;amp;&amp;amp; (__FPU_USED == 1)&lt;br /&gt;
    SCB-&amp;gt;CPACR |= ((3UL &amp;lt;&amp;lt; 10*2)|(3UL &amp;lt;&amp;lt; 11*2));  /* set CP10 and CP11 Full Access */&lt;br /&gt;
  #endif&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
__FPU_PRESENT wird in der &#039;&#039;&#039;&#039;&#039;stm32f4xx.h&#039;&#039;&#039;&#039;&#039; definiert.&lt;br /&gt;
__FPU_USED wird von der IDE übernommen (siehe Build-Log): &#039;&#039;&#039;&#039;&#039;-D__FPU_USED&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Außerdem wird der Compiler von der IDE standardmäßig mit dem Argument &#039;&#039;&#039;&#039;&#039;-mfloat-abi=hard&#039;&#039;&#039;&#039;&#039; aufgerufen, wodurch FPU-Instructions erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
====FPU abschalten====&lt;br /&gt;
Um die FPU ab zu schalten (Mir würde jetzt nur Strom sparen als Grund einfallen) geht man wie folgt vor:&lt;br /&gt;
&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick Build options -&amp;gt; Device -&amp;gt; Policy&#039;&#039;&#039;&#039;&#039; wählt man &#039;&#039;&#039;&#039;&#039;Use target settings&#039;&#039;&#039;&#039;&#039; und über nimmt die Einstellungen, die vorher dort eingetragen waren, allerdings lässt man das Feld &#039;&#039;&#039;&#039;&#039;FP-hardware&#039;&#039;&#039;&#039;&#039; frei.&lt;br /&gt;
&lt;br /&gt;
[[Datei:fpu_1.png|FPU Abschalten Schritt 1]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;Compiler Settings -&amp;gt; Policy&#039;&#039;&#039;&#039;&#039; wählt man dann &#039;&#039;&#039;&#039;&#039;Use target options only&#039;&#039;&#039;&#039;&#039;. Dann kann man unter &#039;&#039;&#039;&#039;&#039;Categories&#039;&#039;&#039;&#039;&#039; die Option &#039;&#039;&#039;&#039;&#039;ARM FPU architecture&#039;&#039;&#039;&#039;&#039; auswählen. Dort stehen dann drei Möglichkeiten für die FPU zur Verfügung:&lt;br /&gt;
&lt;br /&gt;
1. Software-FPU-Library für Gleitkomma-Berechnung verwenden - Keine FPU-Instructions werden generiert (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=soft&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
2. Eine Mischung aus Software- und Hardware-FPU wird verwendet (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=softfp&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
3. Hardware-FPU wird für Gleitkomma-Berechnungen verwendet (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=hard&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
[[Datei:fpu_2.png|FPU Abschalten Schritt 2]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Um die FPU ab zu schalten wählt man natürlich die erste Möglichkeit.&lt;br /&gt;
Bei der 2. und 3. Möglichkeit fügt die IDE auch den Define &#039;&#039;&#039;&#039;&#039;__FPU_USED&#039;&#039;&#039;&#039;&#039; hinzu. Bei Der ersten Möglichkeit nicht. Der Code muss also nicht verändert / auskommentiert werden.&lt;br /&gt;
&lt;br /&gt;
Um die FPU wieder zu aktivieren müssen alle Schritte wieder rückgängig gemacht werden.&lt;br /&gt;
&lt;br /&gt;
Am besten ist es einfach mal alle Möglichkeiten im Einzelschritt durch zu probieren. Dann stellt man schnell fest, ob die FPU aktiviert wir oder nicht. Ein Blick in den erweiterten &#039;&#039;&#039;&#039;&#039;Build-Log&#039;&#039;&#039;&#039;&#039; gibt auch schnell Aufschluss darüber, wie der Compiler aufgerufen wird (siehe Kapitel [http://www.mikrocontroller.net/articles/STM32_-_Einstieg_mit_Em::Blocks#Compilieren Compilieren]).&lt;br /&gt;
&lt;br /&gt;
====Test Programm für die FPU====&lt;br /&gt;
Hier ein kleines Testprogramm, dass misst wie viele Taktzyklen für eine Gleitkomma-Multiplikation gebraucht werden. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define CORE_SysTickEn()    (*((u32*)0xE0001000)) = 0x40000001&lt;br /&gt;
#define CORE_SysTickDis()   (*((u32*)0xE0001000)) = 0x40000000&lt;br /&gt;
#define CORE_GetSysTick()   (*((u32*)0xE0001004))&lt;br /&gt;
&lt;br /&gt;
uint32_t t1, t2, dt;&lt;br /&gt;
float x, y, z;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    x = 53.64f;&lt;br /&gt;
    y = 0.27f;&lt;br /&gt;
&lt;br /&gt;
    CORE_SysTickEn();&lt;br /&gt;
    t1 = CORE_GetSysTick();&lt;br /&gt;
&lt;br /&gt;
    z = x * y;&lt;br /&gt;
&lt;br /&gt;
    t2 = CORE_GetSysTick();&lt;br /&gt;
    CORE_SysTickDis();&lt;br /&gt;
&lt;br /&gt;
    dt = t2 - t1;&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mein Ergebnis:&lt;br /&gt;
*Mit Hardware-FPU:  dt = 25&lt;br /&gt;
*Ohne Hardware-FPU: dt = 83&lt;br /&gt;
&lt;br /&gt;
==Booten aus dem SRAM==&lt;br /&gt;
STM32 Controller haben die Möglichkeit Code aus dem Flash als auch aus dem SRAM auszuführen. Um eine Anwenung per Debugger in des SRAM zu laden sind nur wenige Schritte erforderlich:&lt;br /&gt;
&lt;br /&gt;
*Um das Linkerscript für den SRAM zu verwenden geht man zu: &#039;&#039;&#039;&#039;&#039;Build options... -&amp;gt; Device&#039;&#039;&#039;&#039;&#039; dort wählt man unter &#039;&#039;&#039;&#039;&#039;Policy&#039;&#039;&#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;Use target settings&#039;&#039;&#039;&#039;&#039; aus und übernimmt die vorherigen Einstellungen, nur unter &#039;&#039;&#039;&#039;&#039;Linker script*&#039;&#039;&#039;&#039;&#039; gibt man &#039;&#039;&#039;&#039;&#039;.\stm32f407vg_sram.ld&#039;&#039;&#039;&#039;&#039; an&lt;br /&gt;
&lt;br /&gt;
*Dann muss man noch unter &#039;&#039;&#039;&#039;&#039;Debug -&amp;gt; Interfaces -&amp;gt; Settings&#039;&#039;&#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;Vector table start&#039;&#039;&#039;&#039;&#039; auf 0x20000000 ändern und &#039;&#039;&#039;&#039;&#039;Execute from RAM&#039;&#039;&#039;&#039;&#039; auswählen.&lt;br /&gt;
&lt;br /&gt;
Anschließend kann man die Anwendung ganz normal debuggen. Nach einem Reset muss die Anwenung erneut mit dem Debugger gestartet werden.&lt;br /&gt;
&lt;br /&gt;
=Fortsetzung folgt..=&lt;br /&gt;
Kritik, Wünsche usw. sind gerne erwünscht, am besten hier in den Thread posten: [http://www.mikrocontroller.net/topic/323750 Neues STM32 Tutorial]&lt;br /&gt;
&lt;br /&gt;
[[Category:ARM]]&lt;br /&gt;
[[Category:STM32]]&lt;/div&gt;</summary>
		<author><name>Avrprogger</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=STM32_-_Einstieg_mit_Em::Blocks&amp;diff=81504</id>
		<title>STM32 - Einstieg mit Em::Blocks</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=STM32_-_Einstieg_mit_Em::Blocks&amp;diff=81504"/>
		<updated>2014-02-10T15:24:49Z</updated>

		<summary type="html">&lt;p&gt;Avrprogger: vbn&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In diesem Tutorial werde ich versuchen, möglichst einfach, die ersten Schritte zur Entwicklung von STM32 Anwenungen mit der Em::Blocks IDE zu erklären. Hier soll nicht so stark auf die einzelnen Peripherie-Module der Controller eingegangen werden, sondern mehr auf die IDE und die verschieden Libraries, wie die CMSIS Library, die DSP-Library, die Standard-Peripheral-Library, die USB-Library und vllt. über Ethernet. Ich denke ein Kapitel zu FreeRTOS wird es auch geben. Auserdem steht im Vordergrund Sachen wie z.B. booten aus dem SRAM, In-Application-Programming, FPU, Core-Coupled-RAM usw. Mal sehn wie weit ich komme ;)&lt;br /&gt;
&lt;br /&gt;
==Die Entwicklungsumgebung==&lt;br /&gt;
===Hardware===&lt;br /&gt;
Zum testen der Anwendungen, benutze ich das STM32F4-Discovery Board, welches einen Debugger, Peripherie und natürlich einen STM32 Controller (STM32F407VGT6) enthält. Deshalb sind alle Beispiele hier für den STM32F407VG Controller ausgelegt, können aber meisten 1:1 auf andere Controller portiert werden. Ich werde auch möglichsts keine STM32F4-Discovery Board spezifischen Libraries verwenden, damit der Portierungs-Vorgang möglichsts einfach bleibt.&lt;br /&gt;
&lt;br /&gt;
===Software===&lt;br /&gt;
In diesem Tutorial verwende ich [http://www.emblocks.org/ Em::Blocks] als IDE. Em::Blocks ist eine kostenlose, uneingeschränkte IDE, die alle STM32 Mikrcontroller unterstützt und sehr einfach zu bedienen ist.&lt;br /&gt;
nach dem Download kann die IDE per Dialog, sehr einfach, installiert werden. Als Compiler beinhaltet Em::Blocks den &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
Die IDE unterstützt zurzeit den ST-Link, den J-Link und es gibt eine Generic-Vorlage, durch welche andere Debugger konfiguriert werden können.&lt;br /&gt;
&lt;br /&gt;
Außerdem muss noch der passende Treiber für den Debugger installiert werden. Verwendet man ein Discovery-Board muss der [http://www.st.com/web/catalog/tools/FM146/CL1984/SC724/SS1677/PF251168 ST-Link/V2]-Treiber heruntergeladen und installiert werden. (Die Installation muss evtl. als Administrator ausgeführt werden, da sonst die Installation unvollständig wird.) Nach der Installation des Treibers kann man den Debugger über die entsprechende USB Schnittstelle an den PC anschließen und es sollte die Meldung von Windows kommen, dass der richtige Treiber gefunden wurde.&lt;br /&gt;
&lt;br /&gt;
===Libraries===&lt;br /&gt;
Zum programmieren benötigt man noch die [http://www.arm.com/products/processors/cortex-m/cortex-microcontroller-software-interface-standard.php CMSIS] und die Standard-Peripheral-Library (z.B. für die F4 Controller [http://www.st.com/stonline/stappl/productcatalog/app?page=partNumberSearchPage&amp;amp;levelid=SS1577&amp;amp;parentid=1743&amp;amp;resourcetype=SW Standard-Peripheral-Library-F4]), die man am besten in einen Ordner (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\STM32&#039;&#039;&#039;&#039;&#039;) entpackt&lt;br /&gt;
&lt;br /&gt;
==Basis-Wissen zur IDE==&lt;br /&gt;
Einige Grundfunktionalitäten der IDE:&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von Dateien zum Projekt===&lt;br /&gt;
Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf &amp;lt;ProjektName&amp;gt; -&amp;gt; Add files...&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Enfernen von Dateien aus dem Projekt===&lt;br /&gt;
Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf die Datei / mehrere Dateien auswählen -&amp;gt; Remove file from project&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
Die Dateien werden lediglich aus dem Projekt entfernt und nicht von der Festplatte gelöscht.&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von Include-Pfaden===&lt;br /&gt;
Sofern die Include-Datei(en) nicht im standard Include-Ordner &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; des Projektes liegen, muss man den Pfad zum Projekt hinzufügen, damit der Compiler die Include-Dateien später auch finden kann. Man geht wie folgt vor: Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf &amp;lt;ProjektName&amp;gt; -&amp;gt; Build options... -&amp;gt; Search Directories -&amp;gt; Add&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Compilieren===&lt;br /&gt;
Entweder über das &#039;&#039;&#039;&#039;&#039;Build&#039;&#039;&#039;&#039;&#039; Menü oder über &#039;&#039;&#039;&#039;&#039;F7&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Um eine genau Ausgabe des Compiler-Aufrufes mit allen Argumenten zu bekommen, geht man im &#039;&#039;&#039;&#039;&#039;Settings&#039;&#039;&#039;&#039;&#039; Menü auf &#039;&#039;&#039;&#039;&#039;Tools...&#039;&#039;&#039;&#039;&#039; und dann auf &#039;&#039;&#039;&#039;&#039;Toolchain executables&#039;&#039;&#039;&#039;&#039;. Ganz unten, unter &#039;&#039;&#039;&#039;&#039;Logging&#039;&#039;&#039;&#039;&#039; kann man dann &#039;&#039;&#039;&#039;&#039;Full command line&#039;&#039;&#039;&#039;&#039; auswählen.&lt;br /&gt;
&lt;br /&gt;
===Debuggen===&lt;br /&gt;
*Als erstes den Debugger starten über das &#039;&#039;&#039;&#039;&#039;Debug&#039;&#039;&#039;&#039;&#039; Menü und &#039;&#039;&#039;&#039;&#039;Start/stop Debug Session&#039;&#039;&#039;&#039;&#039; oder über &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
*Danach läuft die Anwendung auf dem Controller und warten im &#039;&#039;&#039;&#039;&#039;Reset_Handler&#039;&#039;&#039;&#039;&#039; auf Einzelschritt- bzw. Run- Befehle (&#039;&#039;&#039;&#039;&#039;F5, F10, F11&#039;&#039;&#039;&#039;&#039; usw..(siehe &#039;&#039;&#039;&#039;&#039;Debug-Menü&#039;&#039;&#039;&#039;&#039; für alle Möglichkeiten))&lt;br /&gt;
&lt;br /&gt;
*Mit &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039; wird die Debug-Session auch wieder beendet&lt;br /&gt;
&lt;br /&gt;
*Unter &#039;&#039;&#039;&#039;&#039;Debug -&amp;gt; Interfaces -&amp;gt; Target settings&#039;&#039;&#039;&#039;&#039; können Eigenschaften, wie z.B &#039;&#039;&#039;&#039;&#039;Run to main()&#039;&#039;&#039;&#039;&#039; aktiviert werden.&lt;br /&gt;
&lt;br /&gt;
===Projekt als Template abspeichern===&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;File -&amp;gt; Save project as template...&#039;&#039;&#039;&#039;&#039;. Das Template erscheint dann im Projekt-Dialog unter &#039;&#039;&#039;&#039;&#039;User templates&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Das erste Projekt erstellen==&lt;br /&gt;
Hier erkläre ich, wie man am Besten (aus meiner Sicht), ein neues Projekt von Grund auf erstellt, sodass man hinterher, den Controller-Kern über die CMSIS-Library und die Peripherie über die Register steuern kann.&lt;br /&gt;
&lt;br /&gt;
===1. Projekt mit der IDE erstellen===&lt;br /&gt;
Nach der Installation der oben beschriebenen Komponenten erstellt man am besten ein Verzeichnis (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\EmBlocks&#039;&#039;&#039;&#039;&#039;), indem später alle Projekte gespeichert werden. Für Libraries kann man auch noch ein Verzeichnis (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\STM32&#039;&#039;&#039;&#039;&#039;) erstellen, wo alle Libraries gespeichert werden, die man für die Projekt brauchen.&lt;br /&gt;
&lt;br /&gt;
Als nächstes starten man EmBlocks. Bei dem ersten Start öffnet sich ein Fenster, wo verschiedene Compiler angezeigt werden, die Em::Blocks findet. Dort wählt man den &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039; aus und klickt &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039;. Nun sollte sich das Hauptfenster von Em::Blocks öffnen. Über &#039;&#039;&#039;&#039;&#039;Create a new Project&#039;&#039;&#039;&#039;&#039; oder &#039;&#039;&#039;&#039;&#039;File -&amp;gt; New -&amp;gt; Project&#039;&#039;&#039;&#039;&#039; ruft man den Projekt-Dialog auf und kann ein neues Projekt erzeugen.&lt;br /&gt;
&lt;br /&gt;
Auf der Ersten Seite wählen man den &#039;&#039;&#039;&#039;&#039;STmicro-ARM&#039;&#039;&#039;&#039;&#039; Projekt-Typ aus.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_1.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auf der nächsten Seite wird man darauf hingewiesen, dass das der entsprechende Projekt-Typ-Dialog ausgeführt wird. Hier kann man ein Häkchen bei &#039;&#039;&#039;&#039;&#039;Skip this page next time&#039;&#039;&#039;&#039;&#039; setzen und auf &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; klicken.&lt;br /&gt;
&lt;br /&gt;
Im nächsten Schritt wählen man das zuvor erstellt Verzeichnis unter &#039;&#039;&#039;&#039;&#039;Folder to create Project in&#039;&#039;&#039;&#039;&#039; aus, indem später alle Projekt gespeichert werden. Außerdem geben wir dem Projekt einen Namen (z.B. &#039;&#039;&#039;&#039;&#039;FirstProject&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_2.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danach muss man einen Compiler auswählen und bestimmen, welche Projekt-Konfigurationen erszeugt werden sollen. Unter &#039;&#039;&#039;&#039;&#039;Compiler&#039;&#039;&#039;&#039;&#039; wählt man &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039; und man kann das Häkchen bei &#039;&#039;&#039;&#039;&#039;Create &amp;quot;Release&amp;quot; configuration&#039;&#039;&#039;&#039;&#039; entfernen, da diese unnötig ist, die Debug-Konfiguration sollte eig. immer ausreichen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_3.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auf den folgenden Seite wird der Controller ausgewählt. Verwendet man ein STM32F4-Discovery Board müssen folgende Dinge gewählt werden: &#039;&#039;&#039;&#039;&#039;Cortex_M4 (F3xx - F4xx) -&amp;gt; STM32F4xx (Cortex M4 with FPU) -&amp;gt; STM32F407VG&#039;&#039;&#039;&#039;&#039;. Leider sind die Auswahl Möglichkeiten nicht ganz richtig, da auch die F3 Controller einen Cortex M4 Kern und eine FPU haben (Ist aber nicht so wichtig, ist nur eine formale Sache). Außerdem entfernt man das Häkchen bei &#039;&#039;&#039;&#039;&#039;Standard Peripherals Library&#039;&#039;&#039;&#039;&#039; (Wie man die Standard-Peripheral-Library einbindet und verwendet erkläre ich später). Man kann auch das Häkchen bei &#039;&#039;&#039;&#039;&#039;Create hex file for Realease target&#039;&#039;&#039;&#039;&#039; entfernen.&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;Stack Size&#039;&#039;&#039;&#039;&#039; und &#039;&#039;&#039;&#039;&#039;Heap Size&#039;&#039;&#039;&#039;&#039; wird die Größe von Stack und Heap festgelegt. Für eine erste Anwendung kann man die Einstellungen so lassen (Stack-Size: 0x0100 =&amp;gt; 256 Byte Stack und Heap-Size: 0x0000 =&amp;gt; kein Heap). Mit &#039;&#039;&#039;&#039;&#039;Finish&#039;&#039;&#039;&#039;&#039; ist der Projekt Dialog abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_4.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danach sollten sich zwei neue Fenster öffnen, um die Debug-Eigenschaften fest zu legen.&lt;br /&gt;
Verwendet man ein Discovery Board/ST-Link müssen die Einstellungen wie auf dem Bild gewählt werden. Über den Button &#039;&#039;&#039;&#039;&#039;Settings&#039;&#039;&#039;&#039;&#039; öffnet sich das zweite Fenster, falls sich dieses nicht schon von alleine öffnen sollte. Nach den Schließen der Fenster über &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; ist der Projekt Dialog beendet und ein neues Projekt steht zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_5_1.png|Debug Eigenschaften 1. Fenster]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_5_2.png|Debug Eigenschaften 2. Fenster]]&lt;br /&gt;
&lt;br /&gt;
===2. CMSIS-Library und Startup-Code hinzufügen===&lt;br /&gt;
Wenn man sich, nachdem man ein neues Projekt in der IDE erstellt hat, die bereits vorhandenen Dateien im Projekt ansieht, stellt man fest, das bereits ein Ordner &#039;&#039;&#039;&#039;&#039;cmsis&#039;&#039;&#039;&#039;&#039; existiert, der einige wichtige Include-Dateien der CMSIS-Library enthält. Allerdings sind das wirklich nur die wichtigsten Include-Dateien der CMSIS-Library und dazu noch, die aus einer älternen Version. Ich ziehe es deshalb vor die &amp;quot;Mini-CMSIS-Libraray&amp;quot; und die &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c/.h&#039;&#039;&#039;&#039;&#039; Dateien des Projektes durch aktuellere Versionen zu ersetzen. So ist später auch die Integration  von anderen Libraries, wie z.B. der CMSIS-DSP-Libarary einfacher.  &lt;br /&gt;
&lt;br /&gt;
Zunächst gehen man in das Projekt-Verzeichnis und löscht:&lt;br /&gt;
*Den Ordner &#039;&#039;&#039;&#039;&#039;cmsis&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Alle Dateien im Include Verzeichnis &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; im &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner&lt;br /&gt;
&lt;br /&gt;
Außerdem entfernt man auch alle gelöschten Dateien in der IDE aus dem Projekt mit &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Rechts Klick -&amp;gt; Remove file from project&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Es sollte folgende Verzeichnis Struktur überbleiben:&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_6.png|Überbleibende Dateien]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Jetzt müssen die gelöschten Dateien durch die aktuelleren ersetzt werden.&lt;br /&gt;
&lt;br /&gt;
*Dazu kopieren man den gesamten Ordner &#039;&#039;&#039;&#039;&#039;CMSIS&#039;&#039;&#039;&#039;&#039; aus dem CMSIS Download in das Projekt Verzeichnis.&lt;br /&gt;
&lt;br /&gt;
*Aus dem Standard-Peripheral-Library Download kopiert man von &#039;&#039;&#039;&#039;&#039;Libraries\CMSIS\Device\ST\STM32F4xx\Include&#039;&#039;&#039;&#039;&#039; alle Dateien in den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projekt Verzeichnisses&lt;br /&gt;
&lt;br /&gt;
*Aus der Standard-Peripheral-Library kopieren man ebenfalls von &#039;&#039;&#039;&#039;&#039;Libraries\CMSIS\Device\ST\STM32F4xx\Source\Templates&#039;&#039;&#039;&#039;&#039; die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; in den &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner des Projekts&lt;br /&gt;
&lt;br /&gt;
Anschließend müssen die neuen Dateien in der IDE dem Projekt hinzugefügt werden. Dazu benutzt man &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Rechts Klick -&amp;gt; Add files&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
*Aus dem &#039;&#039;&#039;&#039;&#039;CMSIS&#039;&#039;&#039;&#039;&#039; Ordner im Projekt Verzeichnis werden aus den Unterorder &#039;&#039;&#039;&#039;&#039;Include&#039;&#039;&#039;&#039;&#039; folgende Dateien dem Projekt hinzugefügt:&lt;br /&gt;
**arm_common_tables.h&lt;br /&gt;
**arm_const_structs.h&lt;br /&gt;
**arm_math.h&lt;br /&gt;
**core_cm4.h&lt;br /&gt;
**core_cm4_simd.h&lt;br /&gt;
**core_cmFunc.h&lt;br /&gt;
**core_cmInstr.h&lt;br /&gt;
*Alle Dateien aus den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projektes&lt;br /&gt;
*Die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; aus dem &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner&lt;br /&gt;
&lt;br /&gt;
So sollte die Struktur dann aussehen:&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_7.png|Anwenungs-Grundgerüst]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Da einige Dateien der Libraries später bearbeitet werden müssen und Schreibgeschützt sind, weise ich hier schonmal darauf hin, das der Schreibschutz in der IDE über &#039;&#039;&#039;&#039;&#039;Rechts Klick auf die Datei -&amp;gt; Properties -&amp;gt; Häkchen bei &amp;quot;File is read only&amp;quot; entfernen&#039;&#039;&#039;&#039;&#039; entfert werden kann.&lt;br /&gt;
&lt;br /&gt;
Damit die IDE die Header-Dateien der CMSIS Library auch finden kann, weil diese ja nicht im standard Include Ordner &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; liegen, muss unter &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Build Options -&amp;gt; Search Directories&#039;&#039;&#039;&#039;&#039; der Pfad &#039;&#039;&#039;&#039;&#039;CMSIS\Include&#039;&#039;&#039;&#039;&#039; hinzugefügt werden.&lt;br /&gt;
&lt;br /&gt;
Compiliert man jetzt das Projekt mit &#039;&#039;&#039;&#039;&#039;F7&#039;&#039;&#039;&#039;&#039; gibt es ein paar Fehler Meldungen, weil keine Controller-Reihe ausgewählt wurde. Ebenfalls unter &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Build Options -&amp;gt; Compiler Settings -&amp;gt; #defines&#039;&#039;&#039;&#039;&#039; wird der Define &#039;&#039;&#039;&#039;&#039;STM32F40_41xxx&#039;&#039;&#039;&#039;&#039; hinzugefügt.&lt;br /&gt;
&lt;br /&gt;
Beim erneuten Compilieren sollten sich nun keine neuen Fehler ergeben.&lt;br /&gt;
&lt;br /&gt;
===Das erste Programm===&lt;br /&gt;
Nachdem ein grundsätzliches &amp;quot;Gerüst&amp;quot; fertig ist, kann man den ersten Code schreiben.&lt;br /&gt;
main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC-&amp;gt;AHB1ENR |= RCC_AHB1ENR_GPIODEN;    //Takt für GPIO aktivieren&lt;br /&gt;
    GPIOD-&amp;gt;MODER |= GPIO_MODER_MODER15_0;   //GPIOD Pin15 als Ausgang&lt;br /&gt;
    GPIOD-&amp;gt;BSRRL |= GPIO_BSRR_BS_15;        //GPIOD Pin15 auf High ziehen&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039; wird dann der Debugger gestartet. Hat der Debugger das Projekt erfolgreich übertragen kann die Ausführung mit &#039;&#039;&#039;&#039;&#039;F5&#039;&#039;&#039;&#039;&#039; begonnen werden.&lt;br /&gt;
&lt;br /&gt;
==Einbinden der Standard-Peripheral-Library==&lt;br /&gt;
Um nicht immer die einzelnen Register, wie im ersten &amp;quot;bare-metal&amp;quot; Beispiel, aus dem Reference-Manual zu suchen und zu beschreiben, gibt es von ST die Standard Peripheral Library, die diese Aufgaben übernimmt und mit der sich die &amp;quot;normale/grundlegende&amp;quot; (Alles außer USB und Ethernet) Peripherie recht einfach steuern lässt. Um die Library zu verwenden erzeugt man wie oben beschrieben ein neues Grundgerüst und kopiert als erstes den Ordner &#039;&#039;&#039;&#039;&#039;Libraries\STM32F4xx_StdPeriph_Driver&#039;&#039;&#039;&#039;&#039; aus dem Standard-Peripheral-Library Download in das Projekt-Verzeichnis. Außerdem muss man die Datei &#039;&#039;&#039;&#039;&#039;Project\STM32F4xx_StdPeriph_Templates\stm32f4xx_conf.h&#039;&#039;&#039;&#039;&#039; ebenfalls aus dem Standard-Peripheral-Library Download in den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projektes kopieren. In der IDE fügt man den Include-Path &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\inc&#039;&#039;&#039;&#039;&#039; hinzufügen, wie bei der CMSIS-Library (s.o.).&lt;br /&gt;
Außerdem muss noch &#039;&#039;&#039;&#039;&#039;USE_STDPERIPH_DRIVER&#039;&#039;&#039;&#039;&#039; als Define in der IDE hinzugefügt werden (s.o.).&lt;br /&gt;
Danach fügt man die Source- und Include-Dateien aus dem Ordner &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\inc&#039;&#039;&#039;&#039;&#039; und &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\src&#039;&#039;&#039;&#039;&#039; dem Project mit &#039;&#039;&#039;&#039;&#039;&amp;lt;Project Name&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Add files&#039;&#039;&#039;&#039;&#039; hinzu, allerdings nur die, für welche auch der Controller die entsprechende Peripherie besitzt. Beim STM32F4-Discovery Board / STM32F407VG Controller dürfen also nicht folgende Dateien nicht mit hinzugefügt werden, weil diese Peripherie nur bei anderen Controller vorhanden ist:&lt;br /&gt;
&lt;br /&gt;
*stm32f4xx_dma2d.c/.h&lt;br /&gt;
*stm32f4xx_fmc.c/.h&lt;br /&gt;
*stm32f4xx_ltdc.c/.h&lt;br /&gt;
*stm32f4xx_sai.c/.h&lt;br /&gt;
&lt;br /&gt;
Daraus resultiert folgende Struktur:&lt;br /&gt;
&lt;br /&gt;
[[Datei:stdperiphlib_2.png|Header-Struktur]] [[Datei:stdperiphlib_1.png|Source-Struktur]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Anschließen kann die Standard-Peripheral-Library benutz werden.&lt;br /&gt;
main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);&lt;br /&gt;
&lt;br /&gt;
    GPIO_InitTypeDef GPIOD_InitStructure;&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Mode = GPIO_Mode_OUT;     //Als Ausgang&lt;br /&gt;
    GPIOD_InitStructure.GPIO_OType = GPIO_OType_PP;    //Push-Pull Betrieb&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Pin = GPIO_Pin_15;        //Pin 15 (STM32F4-Discovery: Blaue LED)&lt;br /&gt;
    GPIOD_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;  //Kein Pull-Up oder Pull-Down Widerstand aktiviert&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Speed = GPIO_Speed_25MHz; //25MHz Update-Rate&lt;br /&gt;
    GPIO_Init(GPIOD, &amp;amp;GPIOD_InitStructure);&lt;br /&gt;
&lt;br /&gt;
    GPIO_SetBits(GPIOD, GPIO_Pin_15);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Takt, FPU usw.==&lt;br /&gt;
===Der Takt===&lt;br /&gt;
Jeder Controller oder Prozessor braucht einen Takt, indem er die einzelnen Maschinen-Befehle abarbeiten kann.&lt;br /&gt;
Bei den STM32 Mikrocontrollern kann dieser Takt aus verschiedenen Quellen kommen:&lt;br /&gt;
&lt;br /&gt;
1. High Speed Internal Oszillator (HSI)&lt;br /&gt;
&lt;br /&gt;
2. High Speed External Oszillator (HSE)&lt;br /&gt;
&lt;br /&gt;
3. Low Speed Internal Oszillator (LSI)&lt;br /&gt;
&lt;br /&gt;
4. Low Speed External Oszillator (LSE)&lt;br /&gt;
&lt;br /&gt;
5. Phase-Locked Loop (PLL) (generiert den Takt aus den ersten vier Taktquellen durch Teiler und Faktoren)&lt;br /&gt;
&lt;br /&gt;
Nach einem Reset wird der Controller aus der HSI Taktquelle versorgt (16MHz beim STM32F407VG). Um die voll Performance des Controllers zu erreichen muss die PLL verwendet werden, welche den Takt durch geschickte Teiler und Faktoren vervielfältigt, sodass am Ende der Controller mit der maximalen Taktfrequenz läuft. Die notwendige Initialisierung der PLL findet in der Funktion &#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; statt. Die PLL erzeugt zunächst einen Basistakt:&lt;br /&gt;
&lt;br /&gt;
PLL_VCO = (F_HSE / PLL_M) * PLL_N&lt;br /&gt;
&lt;br /&gt;
Aus diesem Takt wird dann der Takt für den Controller-Kern abgeleitet:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = PLL_VCO / PLL_P&lt;br /&gt;
&lt;br /&gt;
Und der Takt für SDIO / USB / RNG (48MHz):&lt;br /&gt;
&lt;br /&gt;
48MHz = PLL_VCO / PLL_Q&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Durch weiter Teiler werden, die Takte für die einzelnen Busse erzeugt, da diese nicht alle beliebig schnell betrieben werden dürfen.&lt;br /&gt;
&lt;br /&gt;
Genaue Angaben findet man zu dem jeweiligen Clock-System des Controllers im Reference Manual.&lt;br /&gt;
&lt;br /&gt;
Ein Blick in den &amp;quot;Kommentar-Header&amp;quot; verrät, dass von einem externen (HSE) Oszillator von 25MHz ausgegangen wird, der die PLL versorgen soll.&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((25MHz / PLL_M(25)) * PLL_N(336)) / PLL_P(2) = 168MHz&lt;br /&gt;
&lt;br /&gt;
Allerdings stimmt diese Rechnung natürlich nur, wenn wirklich ein 25MHz Quarz am Controller angeschlossen ist. Auf dem STM32F4-Discovery Board befindet sich aber nur ein 8MHz Quarz. Demnach gilt:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((8MHz / PLL_M(25)) * PLL_N(336)) / PLL_P(2) = 53.76MHz&lt;br /&gt;
&lt;br /&gt;
Der Controller läuft also nur mit 53.76MHz, wenn wie ober beschrieben ein Projekt erstellt wird. Allerdings kann dieses Problem durch ändern von den betroffen Defines behoben werden:&lt;br /&gt;
 &lt;br /&gt;
*Dazu geht man in die &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; Datei und passt zur Vollständigkeit erstmal die zum Controller passende Tabelle im &amp;quot;Kommentar-Header&amp;quot; an (Z.57f):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      HSE Frequency(Hz)                      | 8000000&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      PLL_M                                  | 8&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Danach passt man den PPL_M Define (Z.254) an:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/************************* PLL Parameters *************************************/&lt;br /&gt;
/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */&lt;br /&gt;
#define PLL_M      8&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Außerdem muss man den HSE_VALUE Define in der &#039;&#039;&#039;&#039;&#039;inc/stm32f4xx.h&#039;&#039;&#039;&#039;&#039; angepasst werden (Z.122):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#if !defined  (HSE_VALUE)&lt;br /&gt;
  #define HSE_VALUE    ((uint32_t)8000000) /*!&amp;lt; Value of the External oscillator in Hz */&lt;br /&gt;
&lt;br /&gt;
#endif /* HSE_VALUE */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine neue Berechnung zeigt:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((8MHz / PLL_M(8)) * PLL_N(336)) / PLL_P(2) = 168MHz&lt;br /&gt;
&lt;br /&gt;
Jetzt läuft der Controller mit maximaler Geschwindigkeit.&lt;br /&gt;
&lt;br /&gt;
Die Theorie wird durch folgendes Programm verifiziert. Der geviertelte System-Takt SYSCLK wir am Pin PC9 ausgegeben. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);&lt;br /&gt;
&lt;br /&gt;
    GPIO_InitTypeDef GPIOC_InitStructure;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Mode = GPIO_Mode_AF;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_OType = GPIO_OType_PP;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Pin = GPIO_Pin_9;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;&lt;br /&gt;
    GPIO_Init(GPIOC, &amp;amp;GPIOC_InitStructure);&lt;br /&gt;
&lt;br /&gt;
    RCC_MCO2Config(RCC_MCO2Source_SYSCLK, RCC_MCO2Div_4);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Die FPU===&lt;br /&gt;
====Allgemeines====&lt;br /&gt;
Damit die FPU richtig verwendet wird, müssen normalerweise zwei Bedingungen erfüllt sein:&lt;br /&gt;
&lt;br /&gt;
1. Der Controller muss in der Initialisierung-Funktion &#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; in &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; die FPU Hardware-seitig aktivieren&lt;br /&gt;
&lt;br /&gt;
2. Damit die FPU auch was zu tuen bekommt, müssen vom Compiler FPU-Instructions erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
Die Em::Blocks IDE verwendet standardmäßig die FPU, wenn eine Vorhanden ist. Hier wird die FPU Hardware-seitig aktiviert (&#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; Z.341):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* FPU settings ------------------------------------------------------------*/&lt;br /&gt;
  #if (__FPU_PRESENT == 1) &amp;amp;&amp;amp; (__FPU_USED == 1)&lt;br /&gt;
    SCB-&amp;gt;CPACR |= ((3UL &amp;lt;&amp;lt; 10*2)|(3UL &amp;lt;&amp;lt; 11*2));  /* set CP10 and CP11 Full Access */&lt;br /&gt;
  #endif&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
__FPU_PRESENT wird in der &#039;&#039;&#039;&#039;&#039;stm32f4xx.h&#039;&#039;&#039;&#039;&#039; definiert.&lt;br /&gt;
__FPU_USED wird von der IDE übernommen (siehe Build-Log): &#039;&#039;&#039;&#039;&#039;-D__FPU_USED&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Außerdem wird der Compiler von der IDE standardmäßig mit dem Argument &#039;&#039;&#039;&#039;&#039;-mfloat-abi=hard&#039;&#039;&#039;&#039;&#039; aufgerufen, wodurch FPU-Instructions erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
====FPU abschalten====&lt;br /&gt;
Um die FPU ab zu schalten (Mir würde jetzt nur Strom sparen als Grund einfallen) geht man wie folgt vor:&lt;br /&gt;
&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick Build options -&amp;gt; Device -&amp;gt; Policy&#039;&#039;&#039;&#039;&#039; wählt man &#039;&#039;&#039;&#039;&#039;Use target settings&#039;&#039;&#039;&#039;&#039; und über nimmt die Einstellungen, die vorher dort eingetragen waren, allerdings lässt man das Feld &#039;&#039;&#039;&#039;&#039;FP-hardware&#039;&#039;&#039;&#039;&#039; frei.&lt;br /&gt;
&lt;br /&gt;
[[Datei:fpu_1.png|FPU Abschalten Schritt 1]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;Compiler Settings -&amp;gt; Policy&#039;&#039;&#039;&#039;&#039; wählt man dann &#039;&#039;&#039;&#039;&#039;Use target options only&#039;&#039;&#039;&#039;&#039;. Dann kann man unter &#039;&#039;&#039;&#039;&#039;Categories&#039;&#039;&#039;&#039;&#039; die Option &#039;&#039;&#039;&#039;&#039;ARM FPU architecture&#039;&#039;&#039;&#039;&#039; auswählen. Dort stehen dann drei Möglichkeiten für die FPU zur Verfügung:&lt;br /&gt;
&lt;br /&gt;
1. Software-FPU-Library für Gleitkomma-Berechnung verwenden - Keine FPU-Instructions werden generiert (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=soft&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
2. Eine Mischung aus Software- und Hardware-FPU wird verwendet (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=softfp&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
3. Hardware-FPU wird für Gleitkomma-Berechnungen verwendet (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=hard&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
[[Datei:fpu_2.png|FPU Abschalten Schritt 2]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Um die FPU ab zu schalten wählt man natürlich die erste Möglichkeit.&lt;br /&gt;
Bei der 2. und 3. Möglichkeit fügt die IDE auch den Define &#039;&#039;&#039;&#039;&#039;__FPU_USED&#039;&#039;&#039;&#039;&#039; hinzu. Bei Der ersten Möglichkeit nicht. Der Code muss also nicht verändert / auskommentiert werden.&lt;br /&gt;
&lt;br /&gt;
Um die FPU wieder zu aktivieren müssen alle Schritte wieder rückgängig gemacht werden.&lt;br /&gt;
&lt;br /&gt;
Am besten ist es einfach mal alle Möglichkeiten im Einzelschritt durch zu probieren. Dann stellt man schnell fest, ob die FPU aktiviert wir oder nicht. Ein Blick in den erweiterten &#039;&#039;&#039;&#039;&#039;Build-Log&#039;&#039;&#039;&#039;&#039; gibt auch schnell Aufschluss darüber, wie der Compiler aufgerufen wird (siehe Kapitel [http://www.mikrocontroller.net/articles/STM32_-_Einstieg_mit_Em::Blocks#Compilieren Compilieren]).&lt;br /&gt;
&lt;br /&gt;
====Test Programm für die FPU====&lt;br /&gt;
Hier ein kleines Testprogramm, dass misst wie viele Taktzyklen für eine Gleitkomma-Multiplikation gebraucht werden. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define CORE_SysTickEn()    (*((u32*)0xE0001000)) = 0x40000001&lt;br /&gt;
#define CORE_SysTickDis()   (*((u32*)0xE0001000)) = 0x40000000&lt;br /&gt;
#define CORE_GetSysTick()   (*((u32*)0xE0001004))&lt;br /&gt;
&lt;br /&gt;
uint32_t t1, t2, dt;&lt;br /&gt;
float x, y, z;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    x = 53.64f;&lt;br /&gt;
    y = 0.27f;&lt;br /&gt;
&lt;br /&gt;
    CORE_SysTickEn();&lt;br /&gt;
    t1 = CORE_GetSysTick();&lt;br /&gt;
&lt;br /&gt;
    z = x * y;&lt;br /&gt;
&lt;br /&gt;
    t2 = CORE_GetSysTick();&lt;br /&gt;
    CORE_SysTickDis();&lt;br /&gt;
&lt;br /&gt;
    dt = t2 - t1;&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mein Ergebnis:&lt;br /&gt;
*Mit Hardware-FPU:  dt = 25&lt;br /&gt;
*Ohne Hardware-FPU: dt = 83&lt;br /&gt;
&lt;br /&gt;
==Booten aus dem SRAM==&lt;br /&gt;
STM32 Controller haben die Möglichkeit Code aus dem Flash als auch aus dem SRAM auszuführen. Um eine Anwenung per Debugger in des SRAM zu laden sind nur wenige Schritte erforderlich:&lt;br /&gt;
&lt;br /&gt;
*Um das Linkerscript für den SRAM zu verwenden geht man zu: &#039;&#039;&#039;&#039;&#039;Build options... -&amp;gt; Device&#039;&#039;&#039;&#039;&#039; dort wählt man unter &#039;&#039;&#039;&#039;&#039;Policy&#039;&#039;&#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;Use target settings&#039;&#039;&#039;&#039;&#039; aus und übernimmt die vorherigen Einstellungen, nur unter &#039;&#039;&#039;&#039;&#039;Linker script*&#039;&#039;&#039;&#039;&#039; gibt man &#039;&#039;&#039;&#039;&#039;.\stm32f407vg_sram.ld&#039;&#039;&#039;&#039;&#039; an&lt;br /&gt;
&lt;br /&gt;
*Dann muss man noch unter &#039;&#039;&#039;&#039;&#039;Debug -&amp;gt; Interfaces -&amp;gt; Settings&#039;&#039;&#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;Vector table start&#039;&#039;&#039;&#039;&#039; auf 0x20000000 ändern und &#039;&#039;&#039;&#039;&#039;Execute from RAM&#039;&#039;&#039;&#039;&#039; auswählen.&lt;br /&gt;
&lt;br /&gt;
Anschließend kann man die Anwendung ganz normal debuggen. Nach einem Reset muss die Anwenung erneut mit dem Debugger gestartet werden.&lt;br /&gt;
&lt;br /&gt;
=Fortsetzung folgt..=&lt;br /&gt;
Kritik, Wünsche usw. sind gerne erwünscht, am besten hier in den Thread posten: [http://www.mikrocontroller.net/topic/323750 Neues STM32 Tutorial]&lt;br /&gt;
&lt;br /&gt;
[[Category:ARM]]&lt;br /&gt;
[[Category:STM32]]&lt;/div&gt;</summary>
		<author><name>Avrprogger</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=STM32_-_Einstieg_mit_Em::Blocks&amp;diff=81503</id>
		<title>STM32 - Einstieg mit Em::Blocks</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=STM32_-_Einstieg_mit_Em::Blocks&amp;diff=81503"/>
		<updated>2014-02-10T15:22:50Z</updated>

		<summary type="html">&lt;p&gt;Avrprogger: dfhf&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In diesem Tutorial werde ich versuchen, möglichst einfach, die ersten Schritte zur Entwicklung von STM32 Anwenungen mit der Em::Blocks IDE zu erklären. Hier soll nicht so stark auf die einzelnen Peripherie-Module der Controller eingegangen werden, sondern mehr auf die IDE und die verschieden Libraries, wie die CMSIS Library, die DSP-Library, die Standard-Peripheral-Library, die USB-Library und vllt. über Ethernet. Ich denke ein Kapitel zu FreeRTOS wird es auch geben. Auserdem steht im Vordergrund Sachen wie z.B. booten aus dem SRAM, In-Application-Programming, FPU, Core-Coupled-RAM usw. Mal sehn wie weit ich komme ;)&lt;br /&gt;
&lt;br /&gt;
==Die Entwicklungsumgebung==&lt;br /&gt;
===Hardware===&lt;br /&gt;
Zum testen der Anwendungen, benutze ich das STM32F4-Discovery Board, welches einen Debugger, Peripherie und natürlich einen STM32 Controller (STM32F407VGT6) enthält. Deshalb sind alle Beispiele hier für den STM32F407VG Controller ausgelegt, können aber meisten 1:1 auf andere Controller portiert werden. Ich werde auch möglichsts keine STM32F4-Discovery Board spezifischen Libraries verwenden, damit der Portierungs-Vorgang möglichsts einfach bleibt.&lt;br /&gt;
&lt;br /&gt;
===Software===&lt;br /&gt;
In diesem Tutorial verwende ich [http://www.emblocks.org/ Em::Blocks] als IDE. Em::Blocks ist eine kostenlose, uneingeschränkte IDE, die alle STM32 Mikrcontroller unterstützt und sehr einfach zu bedienen ist.&lt;br /&gt;
nach dem Download kann die IDE per Dialog, sehr einfach, installiert werden. Als Compiler beinhaltet Em::Blocks den &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
Die IDE unterstützt zurzeit den ST-Link, den J-Link und es gibt eine Generic-Vorlage, durch welche andere Debugger konfiguriert werden können.&lt;br /&gt;
&lt;br /&gt;
Außerdem muss noch der passende Treiber für den Debugger installiert werden. Verwendet man ein Discovery-Board muss der [http://www.st.com/web/catalog/tools/FM146/CL1984/SC724/SS1677/PF251168 ST-Link/V2]-Treiber heruntergeladen und installiert werden. (Die Installation muss evtl. als Administrator ausgeführt werden, da sonst die Installation unvollständig wird.) Nach der Installation des Treibers kann man den Debugger über die entsprechende USB Schnittstelle an den PC anschließen und es sollte die Meldung von Windows kommen, dass der richtige Treiber gefunden wurde.&lt;br /&gt;
&lt;br /&gt;
===Libraries===&lt;br /&gt;
Zum programmieren benötigt man noch die [http://www.arm.com/products/processors/cortex-m/cortex-microcontroller-software-interface-standard.php CMSIS] und die Standard-Peripheral-Library (z.B. für die F4 Controller [http://www.st.com/stonline/stappl/productcatalog/app?page=partNumberSearchPage&amp;amp;levelid=SS1577&amp;amp;parentid=1743&amp;amp;resourcetype=SW Standard-Peripheral-Library-F4]), die man am besten in einen Ordner (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\STM32&#039;&#039;&#039;&#039;&#039;) entpackt&lt;br /&gt;
&lt;br /&gt;
==Basis-Wissen zur IDE==&lt;br /&gt;
Einige Grundfunktionalitäten der IDE:&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von Dateien zum Projekt===&lt;br /&gt;
Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf &amp;lt;ProjektName&amp;gt; -&amp;gt; Add files...&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Enfernen von Dateien aus dem Projekt===&lt;br /&gt;
Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf die Datei / mehrere Dateien auswählen -&amp;gt; Remove file from project&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
Die Dateien werden lediglich aus dem Projekt entfernt und nicht von der Festplatte gelöscht.&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von Include-Pfaden===&lt;br /&gt;
Sofern die Include-Datei(en) nicht im standard Include-Ordner &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; des Projektes liegen, muss man den Pfad zum Projekt hinzufügen, damit der Compiler die Include-Dateien später auch finden kann. Man geht wie folgt vor: Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf &amp;lt;ProjektName&amp;gt; -&amp;gt; Build options... -&amp;gt; Search Directories -&amp;gt; Add&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Compilieren===&lt;br /&gt;
Entweder über das &#039;&#039;&#039;&#039;&#039;Build&#039;&#039;&#039;&#039;&#039; Menü oder über &#039;&#039;&#039;&#039;&#039;F7&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Um eine genau Ausgabe des Compiler-Aufrufes mit allen Argumenten zu bekommen, geht man im &#039;&#039;&#039;&#039;&#039;Settings&#039;&#039;&#039;&#039;&#039; Menü auf &#039;&#039;&#039;&#039;&#039;Tools...&#039;&#039;&#039;&#039;&#039; und dann auf &#039;&#039;&#039;&#039;&#039;Toolchain executables&#039;&#039;&#039;&#039;&#039;. Ganz unten, unter &#039;&#039;&#039;&#039;&#039;Logging&#039;&#039;&#039;&#039;&#039; kann man dann &#039;&#039;&#039;&#039;&#039;Full command line&#039;&#039;&#039;&#039;&#039; auswählen.&lt;br /&gt;
&lt;br /&gt;
===Debuggen===&lt;br /&gt;
*Als erstes den Debugger starten über das &#039;&#039;&#039;&#039;&#039;Debug&#039;&#039;&#039;&#039;&#039; Menü und &#039;&#039;&#039;&#039;&#039;Start/stop Debug Session&#039;&#039;&#039;&#039;&#039; oder über &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
*Danach läuft die Anwendung auf dem Controller und warten im &#039;&#039;&#039;&#039;&#039;Reset_Handler&#039;&#039;&#039;&#039;&#039; auf Einzelschritt- bzw. Run- Befehle (&#039;&#039;&#039;&#039;&#039;F5, F10, F11&#039;&#039;&#039;&#039;&#039; usw..(siehe &#039;&#039;&#039;&#039;&#039;Debug-Menü&#039;&#039;&#039;&#039;&#039; für alle Möglichkeiten))&lt;br /&gt;
&lt;br /&gt;
*Mit &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039; wird die Debug-Session auch wieder beendet&lt;br /&gt;
&lt;br /&gt;
*Unter &#039;&#039;&#039;&#039;&#039;Debug -&amp;gt; Interfaces -&amp;gt; Target settings&#039;&#039;&#039;&#039;&#039; können Eigenschaften, wie z.B &#039;&#039;&#039;&#039;&#039;Run to main()&#039;&#039;&#039;&#039;&#039; aktiviert werden.&lt;br /&gt;
&lt;br /&gt;
===Projekt als Template abspeichern===&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;File -&amp;gt; Save project as template...&#039;&#039;&#039;&#039;&#039;. Das Template erscheint dann im Projekt-Dialog unter &#039;&#039;&#039;&#039;&#039;User templates&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Das erste Projekt erstellen==&lt;br /&gt;
Hier erkläre ich, wie man am Besten (aus meiner Sicht), ein neues Projekt von Grund auf erstellt, sodass man hinterher, den Controller-Kern über die CMSIS-Library und die Peripherie über die Register steuern kann.&lt;br /&gt;
&lt;br /&gt;
===1. Projekt mit der IDE erstellen===&lt;br /&gt;
Nach der Installation der oben beschriebenen Komponenten erstellt man am besten ein Verzeichnis (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\EmBlocks&#039;&#039;&#039;&#039;&#039;), indem später alle Projekte gespeichert werden. Für Libraries kann man auch noch ein Verzeichnis (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\STM32&#039;&#039;&#039;&#039;&#039;) erstellen, wo alle Libraries gespeichert werden, die man für die Projekt brauchen.&lt;br /&gt;
&lt;br /&gt;
Als nächstes starten man EmBlocks. Bei dem ersten Start öffnet sich ein Fenster, wo verschiedene Compiler angezeigt werden, die Em::Blocks findet. Dort wählt man den &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039; aus und klickt &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039;. Nun sollte sich das Hauptfenster von Em::Blocks öffnen. Über &#039;&#039;&#039;&#039;&#039;Create a new Project&#039;&#039;&#039;&#039;&#039; oder &#039;&#039;&#039;&#039;&#039;File -&amp;gt; New -&amp;gt; Project&#039;&#039;&#039;&#039;&#039; ruft man den Projekt-Dialog auf und kann ein neues Projekt erzeugen.&lt;br /&gt;
&lt;br /&gt;
Auf der Ersten Seite wählen man den &#039;&#039;&#039;&#039;&#039;STmicro-ARM&#039;&#039;&#039;&#039;&#039; Projekt-Typ aus.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_1.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auf der nächsten Seite wird man darauf hingewiesen, dass das der entsprechende Projekt-Typ-Dialog ausgeführt wird. Hier kann man ein Häkchen bei &#039;&#039;&#039;&#039;&#039;Skip this page next time&#039;&#039;&#039;&#039;&#039; setzen und auf &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; klicken.&lt;br /&gt;
&lt;br /&gt;
Im nächsten Schritt wählen man das zuvor erstellt Verzeichnis unter &#039;&#039;&#039;&#039;&#039;Folder to create Project in&#039;&#039;&#039;&#039;&#039; aus, indem später alle Projekt gespeichert werden. Außerdem geben wir dem Projekt einen Namen (z.B. &#039;&#039;&#039;&#039;&#039;FirstProject&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_2.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danach muss man einen Compiler auswählen und bestimmen, welche Projekt-Konfigurationen erszeugt werden sollen. Unter &#039;&#039;&#039;&#039;&#039;Compiler&#039;&#039;&#039;&#039;&#039; wählt man &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039; und man kann das Häkchen bei &#039;&#039;&#039;&#039;&#039;Create &amp;quot;Release&amp;quot; configuration&#039;&#039;&#039;&#039;&#039; entfernen, da diese unnötig ist, die Debug-Konfiguration sollte eig. immer ausreichen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_3.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auf den folgenden Seite wird der Controller ausgewählt. Verwendet man ein STM32F4-Discovery Board müssen folgende Dinge gewählt werden: &#039;&#039;&#039;&#039;&#039;Cortex_M4 (F3xx - F4xx) -&amp;gt; STM32F4xx (Cortex M4 with FPU) -&amp;gt; STM32F407VG&#039;&#039;&#039;&#039;&#039;. Leider sind die Auswahl Möglichkeiten nicht ganz richtig, da auch die F3 Controller einen Cortex M4 Kern und eine FPU haben (Ist aber nicht so wichtig, ist nur eine formale Sache). Außerdem entfernt man das Häkchen bei &#039;&#039;&#039;&#039;&#039;Standard Peripherals Library&#039;&#039;&#039;&#039;&#039; (Wie man die Standard-Peripheral-Library einbindet und verwendet erkläre ich später). Man kann auch das Häkchen bei &#039;&#039;&#039;&#039;&#039;Create hex file for Realease target&#039;&#039;&#039;&#039;&#039; entfernen.&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;Stack Size&#039;&#039;&#039;&#039;&#039; und &#039;&#039;&#039;&#039;&#039;Heap Size&#039;&#039;&#039;&#039;&#039; wird die Größe von Stack und Heap festgelegt. Für eine erste Anwendung kann man die Einstellungen so lassen (Stack-Size: 0x0100 =&amp;gt; 256 Byte Stack und Heap-Size: 0x0000 =&amp;gt; kein Heap). Mit &#039;&#039;&#039;&#039;&#039;Finish&#039;&#039;&#039;&#039;&#039; ist der Projekt Dialog abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_4.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danach sollten sich zwei neue Fenster öffnen, um die Debug-Eigenschaften fest zu legen.&lt;br /&gt;
Verwendet man ein Discovery Board/ST-Link müssen die Einstellungen wie auf dem Bild gewählt werden. Über den Button &#039;&#039;&#039;&#039;&#039;Settings&#039;&#039;&#039;&#039;&#039; öffnet sich das zweite Fenster, falls sich dieses nicht schon von alleine öffnen sollte. Nach den Schließen der Fenster über &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; ist der Projekt Dialog beendet und ein neues Projekt steht zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_5_1.png|Debug Eigenschaften 1. Fenster]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_5_2.png|Debug Eigenschaften 2. Fenster]]&lt;br /&gt;
&lt;br /&gt;
===2. CMSIS-Library und Startup-Code hinzufügen===&lt;br /&gt;
Wenn man sich, nachdem man ein neues Projekt in der IDE erstellt hat, die bereits vorhandenen Dateien im Projekt ansieht, stellt man fest, das bereits ein Ordner &#039;&#039;&#039;&#039;&#039;cmsis&#039;&#039;&#039;&#039;&#039; existiert, der einige wichtige Include-Dateien der CMSIS-Library enthält. Allerdings sind das wirklich nur die wichtigsten Include-Dateien der CMSIS-Library und dazu noch, die aus einer älternen Version. Ich ziehe es deshalb vor die &amp;quot;Mini-CMSIS-Libraray&amp;quot; und die &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c/.h&#039;&#039;&#039;&#039;&#039; Dateien des Projektes durch aktuellere Versionen zu ersetzen. So ist später auch die Integration  von anderen Libraries, wie z.B. der CMSIS-DSP-Libarary einfacher.  &lt;br /&gt;
&lt;br /&gt;
Zunächst gehen man in das Projekt-Verzeichnis und löscht:&lt;br /&gt;
*Den Ordner &#039;&#039;&#039;&#039;&#039;cmsis&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Alle Dateien im Include Verzeichnis &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; im &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner&lt;br /&gt;
&lt;br /&gt;
Außerdem entfernt man auch alle gelöschten Dateien in der IDE aus dem Projekt mit &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Rechts Klick -&amp;gt; Remove file from project&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Es sollte folgende Verzeichnis Struktur überbleiben:&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_6.png|Überbleibende Dateien]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Jetzt müssen die gelöschten Dateien durch die aktuelleren ersetzt werden.&lt;br /&gt;
&lt;br /&gt;
*Dazu kopieren man den gesamten Ordner &#039;&#039;&#039;&#039;&#039;CMSIS&#039;&#039;&#039;&#039;&#039; aus dem CMSIS Download in das Projekt Verzeichnis.&lt;br /&gt;
&lt;br /&gt;
*Aus dem Standard-Peripheral-Library Download kopiert man von &#039;&#039;&#039;&#039;&#039;Libraries\CMSIS\Device\ST\STM32F4xx\Include&#039;&#039;&#039;&#039;&#039; alle Dateien in den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projekt Verzeichnisses&lt;br /&gt;
&lt;br /&gt;
*Aus der Standard-Peripheral-Library kopieren man ebenfalls von &#039;&#039;&#039;&#039;&#039;Libraries\CMSIS\Device\ST\STM32F4xx\Source\Templates&#039;&#039;&#039;&#039;&#039; die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; in den &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner des Projekts&lt;br /&gt;
&lt;br /&gt;
Anschließend müssen die neuen Dateien in der IDE dem Projekt hinzugefügt werden. Dazu benutzt man &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Rechts Klick -&amp;gt; Add files&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
*Aus dem &#039;&#039;&#039;&#039;&#039;CMSIS&#039;&#039;&#039;&#039;&#039; Ordner im Projekt Verzeichnis werden aus den Unterorder &#039;&#039;&#039;&#039;&#039;Include&#039;&#039;&#039;&#039;&#039; folgende Dateien dem Projekt hinzugefügt:&lt;br /&gt;
**arm_common_tables.h&lt;br /&gt;
**arm_const_structs.h&lt;br /&gt;
**arm_math.h&lt;br /&gt;
**core_cm4.h&lt;br /&gt;
**core_cm4_simd.h&lt;br /&gt;
**core_cmFunc.h&lt;br /&gt;
**core_cmInstr.h&lt;br /&gt;
*Alle Dateien aus den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projektes&lt;br /&gt;
*Die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; aus dem &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner&lt;br /&gt;
&lt;br /&gt;
So sollte die Struktur dann aussehen:&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_7.png|Anwenungs-Grundgerüst]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Da einige Dateien der Libraries später bearbeitet werden müssen und Schreibgeschützt sind, weise ich hier schonmal darauf hin, das der Schreibschutz in der IDE über &#039;&#039;&#039;&#039;&#039;Rechts Klick auf die Datei -&amp;gt; Properties -&amp;gt; Häkchen bei &amp;quot;File is read only&amp;quot; entfernen&#039;&#039;&#039;&#039;&#039; entfert werden kann.&lt;br /&gt;
&lt;br /&gt;
Damit die IDE die Header-Dateien der CMSIS Library auch finden kann, weil diese ja nicht im standard Include Ordner &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; liegen, muss unter &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Build Options -&amp;gt; Search Directories&#039;&#039;&#039;&#039;&#039; der Pfad &#039;&#039;&#039;&#039;&#039;CMSIS\Include&#039;&#039;&#039;&#039;&#039; hinzugefügt werden.&lt;br /&gt;
&lt;br /&gt;
Compiliert man jetzt das Projekt mit &#039;&#039;&#039;&#039;&#039;F7&#039;&#039;&#039;&#039;&#039; gibt es ein paar Fehler Meldungen, weil keine Controller-Reihe ausgewählt wurde. Ebenfalls unter &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Build Options -&amp;gt; Compiler Settings -&amp;gt; #defines&#039;&#039;&#039;&#039;&#039; wird der Define &#039;&#039;&#039;&#039;&#039;STM32F40_41xxx&#039;&#039;&#039;&#039;&#039; hinzugefügt.&lt;br /&gt;
&lt;br /&gt;
Beim erneuten Compilieren sollten sich nun keine neuen Fehler ergeben.&lt;br /&gt;
&lt;br /&gt;
===Das erste Programm===&lt;br /&gt;
Nachdem ein grundsätzliches &amp;quot;Gerüst&amp;quot; fertig ist, kann man den ersten Code schreiben.&lt;br /&gt;
main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC-&amp;gt;AHB1ENR |= RCC_AHB1ENR_GPIODEN;    //Takt für GPIO aktivieren&lt;br /&gt;
    GPIOD-&amp;gt;MODER |= GPIO_MODER_MODER15_0;   //GPIOD Pin15 als Ausgang&lt;br /&gt;
    GPIOD-&amp;gt;BSRRL |= GPIO_BSRR_BS_15;        //GPIOD Pin15 auf High ziehen&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039; wird dann der Debugger gestartet. Hat der Debugger das Projekt erfolgreich übertragen kann die Ausführung mit &#039;&#039;&#039;&#039;&#039;F5&#039;&#039;&#039;&#039;&#039; begonnen werden.&lt;br /&gt;
&lt;br /&gt;
==Takt, FPU usw.==&lt;br /&gt;
===Der Takt===&lt;br /&gt;
Jeder Controller oder Prozessor braucht einen Takt, indem er die einzelnen Maschinen-Befehle abarbeiten kann.&lt;br /&gt;
Bei den STM32 Mikrocontrollern kann dieser Takt aus verschiedenen Quellen kommen:&lt;br /&gt;
&lt;br /&gt;
1. High Speed Internal Oszillator (HSI)&lt;br /&gt;
&lt;br /&gt;
2. High Speed External Oszillator (HSE)&lt;br /&gt;
&lt;br /&gt;
3. Low Speed Internal Oszillator (LSI)&lt;br /&gt;
&lt;br /&gt;
4. Low Speed External Oszillator (LSE)&lt;br /&gt;
&lt;br /&gt;
5. Phase-Locked Loop (PLL) (generiert den Takt aus den ersten vier Taktquellen durch Teiler und Faktoren)&lt;br /&gt;
&lt;br /&gt;
Nach einem Reset wird der Controller aus der HSI Taktquelle versorgt (16MHz beim STM32F407VG). Um die voll Performance des Controllers zu erreichen muss die PLL verwendet werden, welche den Takt durch geschickte Teiler und Faktoren vervielfältigt, sodass am Ende der Controller mit der maximalen Taktfrequenz läuft. Die notwendige Initialisierung der PLL findet in der Funktion &#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; statt. Die PLL erzeugt zunächst einen Basistakt:&lt;br /&gt;
&lt;br /&gt;
PLL_VCO = (F_HSE / PLL_M) * PLL_N&lt;br /&gt;
&lt;br /&gt;
Aus diesem Takt wird dann der Takt für den Controller-Kern abgeleitet:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = PLL_VCO / PLL_P&lt;br /&gt;
&lt;br /&gt;
Und der Takt für SDIO / USB / RNG (48MHz):&lt;br /&gt;
&lt;br /&gt;
48MHz = PLL_VCO / PLL_Q&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Durch weiter Teiler werden, die Takte für die einzelnen Busse erzeugt, da diese nicht alle beliebig schnell betrieben werden dürfen.&lt;br /&gt;
&lt;br /&gt;
Genaue Angaben findet man zu dem jeweiligen Clock-System des Controllers im Reference Manual.&lt;br /&gt;
&lt;br /&gt;
Ein Blick in den &amp;quot;Kommentar-Header&amp;quot; verrät, dass von einem externen (HSE) Oszillator von 25MHz ausgegangen wird, der die PLL versorgen soll.&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((25MHz / PLL_M(25)) * PLL_N(336)) / PLL_P(2) = 168MHz&lt;br /&gt;
&lt;br /&gt;
Allerdings stimmt diese Rechnung natürlich nur, wenn wirklich ein 25MHz Quarz am Controller angeschlossen ist. Auf dem STM32F4-Discovery Board befindet sich aber nur ein 8MHz Quarz. Demnach gilt:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((8MHz / PLL_M(25)) * PLL_N(336)) / PLL_P(2) = 53.76MHz&lt;br /&gt;
&lt;br /&gt;
Der Controller läuft also nur mit 53.76MHz, wenn wie ober beschrieben ein Projekt erstellt wird. Allerdings kann dieses Problem durch ändern von den betroffen Defines behoben werden:&lt;br /&gt;
 &lt;br /&gt;
*Dazu geht man in die &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; Datei und passt zur Vollständigkeit erstmal die zum Controller passende Tabelle im &amp;quot;Kommentar-Header&amp;quot; an (Z.57f):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      HSE Frequency(Hz)                      | 8000000&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      PLL_M                                  | 8&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Danach passt man den PPL_M Define (Z.254) an:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/************************* PLL Parameters *************************************/&lt;br /&gt;
/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */&lt;br /&gt;
#define PLL_M      8&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Außerdem muss man den HSE_VALUE Define in der &#039;&#039;&#039;&#039;&#039;inc/stm32f4xx.h&#039;&#039;&#039;&#039;&#039; angepasst werden (Z.122):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#if !defined  (HSE_VALUE)&lt;br /&gt;
  #define HSE_VALUE    ((uint32_t)8000000) /*!&amp;lt; Value of the External oscillator in Hz */&lt;br /&gt;
&lt;br /&gt;
#endif /* HSE_VALUE */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine neue Berechnung zeigt:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((8MHz / PLL_M(8)) * PLL_N(336)) / PLL_P(2) = 168MHz&lt;br /&gt;
&lt;br /&gt;
Jetzt läuft der Controller mit maximaler Geschwindigkeit.&lt;br /&gt;
&lt;br /&gt;
Die Theorie wird durch folgendes Programm verifiziert. Der geviertelte System-Takt SYSCLK wir am Pin PC9 ausgegeben. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);&lt;br /&gt;
&lt;br /&gt;
    GPIO_InitTypeDef GPIOC_InitStructure;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Mode = GPIO_Mode_AF;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_OType = GPIO_OType_PP;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Pin = GPIO_Pin_9;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;&lt;br /&gt;
    GPIO_Init(GPIOC, &amp;amp;GPIOC_InitStructure);&lt;br /&gt;
&lt;br /&gt;
    RCC_MCO2Config(RCC_MCO2Source_SYSCLK, RCC_MCO2Div_4);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Die FPU===&lt;br /&gt;
====Allgemeines====&lt;br /&gt;
Damit die FPU richtig verwendet wird, müssen normalerweise zwei Bedingungen erfüllt sein:&lt;br /&gt;
&lt;br /&gt;
1. Der Controller muss in der Initialisierung-Funktion &#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; in &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; die FPU Hardware-seitig aktivieren&lt;br /&gt;
&lt;br /&gt;
2. Damit die FPU auch was zu tuen bekommt, müssen vom Compiler FPU-Instructions erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
Die Em::Blocks IDE verwendet standardmäßig die FPU, wenn eine Vorhanden ist. Hier wird die FPU Hardware-seitig aktiviert (&#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; Z.341):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* FPU settings ------------------------------------------------------------*/&lt;br /&gt;
  #if (__FPU_PRESENT == 1) &amp;amp;&amp;amp; (__FPU_USED == 1)&lt;br /&gt;
    SCB-&amp;gt;CPACR |= ((3UL &amp;lt;&amp;lt; 10*2)|(3UL &amp;lt;&amp;lt; 11*2));  /* set CP10 and CP11 Full Access */&lt;br /&gt;
  #endif&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
__FPU_PRESENT wird in der &#039;&#039;&#039;&#039;&#039;stm32f4xx.h&#039;&#039;&#039;&#039;&#039; definiert.&lt;br /&gt;
__FPU_USED wird von der IDE übernommen (siehe Build-Log): &#039;&#039;&#039;&#039;&#039;-D__FPU_USED&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Außerdem wird der Compiler von der IDE standardmäßig mit dem Argument &#039;&#039;&#039;&#039;&#039;-mfloat-abi=hard&#039;&#039;&#039;&#039;&#039; aufgerufen, wodurch FPU-Instructions erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
====FPU abschalten====&lt;br /&gt;
Um die FPU ab zu schalten (Mir würde jetzt nur Strom sparen als Grund einfallen) geht man wie folgt vor:&lt;br /&gt;
&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick Build options -&amp;gt; Device -&amp;gt; Policy&#039;&#039;&#039;&#039;&#039; wählt man &#039;&#039;&#039;&#039;&#039;Use target settings&#039;&#039;&#039;&#039;&#039; und über nimmt die Einstellungen, die vorher dort eingetragen waren, allerdings lässt man das Feld &#039;&#039;&#039;&#039;&#039;FP-hardware&#039;&#039;&#039;&#039;&#039; frei.&lt;br /&gt;
&lt;br /&gt;
[[Datei:fpu_1.png|FPU Abschalten Schritt 1]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;Compiler Settings -&amp;gt; Policy&#039;&#039;&#039;&#039;&#039; wählt man dann &#039;&#039;&#039;&#039;&#039;Use target options only&#039;&#039;&#039;&#039;&#039;. Dann kann man unter &#039;&#039;&#039;&#039;&#039;Categories&#039;&#039;&#039;&#039;&#039; die Option &#039;&#039;&#039;&#039;&#039;ARM FPU architecture&#039;&#039;&#039;&#039;&#039; auswählen. Dort stehen dann drei Möglichkeiten für die FPU zur Verfügung:&lt;br /&gt;
&lt;br /&gt;
1. Software-FPU-Library für Gleitkomma-Berechnung verwenden - Keine FPU-Instructions werden generiert (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=soft&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
2. Eine Mischung aus Software- und Hardware-FPU wird verwendet (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=softfp&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
3. Hardware-FPU wird für Gleitkomma-Berechnungen verwendet (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=hard&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
[[Datei:fpu_2.png|FPU Abschalten Schritt 2]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Um die FPU ab zu schalten wählt man natürlich die erste Möglichkeit.&lt;br /&gt;
Bei der 2. und 3. Möglichkeit fügt die IDE auch den Define &#039;&#039;&#039;&#039;&#039;__FPU_USED&#039;&#039;&#039;&#039;&#039; hinzu. Bei Der ersten Möglichkeit nicht. Der Code muss also nicht verändert / auskommentiert werden.&lt;br /&gt;
&lt;br /&gt;
Um die FPU wieder zu aktivieren müssen alle Schritte wieder rückgängig gemacht werden.&lt;br /&gt;
&lt;br /&gt;
Am besten ist es einfach mal alle Möglichkeiten im Einzelschritt durch zu probieren. Dann stellt man schnell fest, ob die FPU aktiviert wir oder nicht. Ein Blick in den erweiterten &#039;&#039;&#039;&#039;&#039;Build-Log&#039;&#039;&#039;&#039;&#039; gibt auch schnell Aufschluss darüber, wie der Compiler aufgerufen wird (siehe Kapitel [http://www.mikrocontroller.net/articles/STM32_-_Einstieg_mit_Em::Blocks#Compilieren Compilieren]).&lt;br /&gt;
&lt;br /&gt;
====Test Programm für die FPU====&lt;br /&gt;
Hier ein kleines Testprogramm, dass misst wie viele Taktzyklen für eine Gleitkomma-Multiplikation gebraucht werden. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define CORE_SysTickEn()    (*((u32*)0xE0001000)) = 0x40000001&lt;br /&gt;
#define CORE_SysTickDis()   (*((u32*)0xE0001000)) = 0x40000000&lt;br /&gt;
#define CORE_GetSysTick()   (*((u32*)0xE0001004))&lt;br /&gt;
&lt;br /&gt;
uint32_t t1, t2, dt;&lt;br /&gt;
float x, y, z;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    x = 53.64f;&lt;br /&gt;
    y = 0.27f;&lt;br /&gt;
&lt;br /&gt;
    CORE_SysTickEn();&lt;br /&gt;
    t1 = CORE_GetSysTick();&lt;br /&gt;
&lt;br /&gt;
    z = x * y;&lt;br /&gt;
&lt;br /&gt;
    t2 = CORE_GetSysTick();&lt;br /&gt;
    CORE_SysTickDis();&lt;br /&gt;
&lt;br /&gt;
    dt = t2 - t1;&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mein Ergebnis:&lt;br /&gt;
*Mit Hardware-FPU:  dt = 25&lt;br /&gt;
*Ohne Hardware-FPU: dt = 83&lt;br /&gt;
&lt;br /&gt;
==Einbinden der Standard Peripheral Library==&lt;br /&gt;
Um nicht immer die einzelnen Register, wie im ersten &amp;quot;bare-metal&amp;quot; Beispiel, aus dem Reference-Manual zu suchen und zu beschreiben, gibt es von ST die Standard Peripheral Library, die diese Aufgaben übernimmt und mit der sich die &amp;quot;normale/grundlegende&amp;quot; (Alles außer USB und Ethernet) Peripherie recht einfach steuern lässt. Um die Library zu verwenden erzeugt man wie oben beschrieben ein neues Grundgerüst und kopiert als erstes den Ordner &#039;&#039;&#039;&#039;&#039;Libraries\STM32F4xx_StdPeriph_Driver&#039;&#039;&#039;&#039;&#039; aus dem Standard-Peripheral-Library Download in das Projekt-Verzeichnis. Außerdem muss man die Datei &#039;&#039;&#039;&#039;&#039;Project\STM32F4xx_StdPeriph_Templates\stm32f4xx_conf.h&#039;&#039;&#039;&#039;&#039; ebenfalls aus dem Standard-Peripheral-Library Download in den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projektes kopieren. In der IDE fügt man den Include-Path &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\inc&#039;&#039;&#039;&#039;&#039; hinzufügen, wie bei der CMSIS-Library (s.o.).&lt;br /&gt;
Außerdem muss noch &#039;&#039;&#039;&#039;&#039;USE_STDPERIPH_DRIVER&#039;&#039;&#039;&#039;&#039; als Define in der IDE hinzugefügt werden (s.o.).&lt;br /&gt;
Danach fügt man die Source- und Include-Dateien aus dem Ordner &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\inc&#039;&#039;&#039;&#039;&#039; und &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\src&#039;&#039;&#039;&#039;&#039; dem Project mit &#039;&#039;&#039;&#039;&#039;&amp;lt;Project Name&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Add files&#039;&#039;&#039;&#039;&#039; hinzu, allerdings nur die, für welche auch der Controller die entsprechende Peripherie besitzt. Beim STM32F4-Discovery Board / STM32F407VG Controller dürfen also nicht folgende Dateien nicht mit hinzugefügt werden, weil diese Peripherie nur bei anderen Controller vorhanden ist:&lt;br /&gt;
&lt;br /&gt;
*stm32f4xx_dma2d.c/.h&lt;br /&gt;
*stm32f4xx_fmc.c/.h&lt;br /&gt;
*stm32f4xx_ltdc.c/.h&lt;br /&gt;
*stm32f4xx_sai.c/.h&lt;br /&gt;
&lt;br /&gt;
Daraus resultiert folgende Struktur:&lt;br /&gt;
&lt;br /&gt;
[[Datei:stdperiphlib_2.png|Header-Struktur]] [[Datei:stdperiphlib_1.png|Source-Struktur]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Anschließen kann die Standard-Peripheral-Library benutz werden.&lt;br /&gt;
main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);&lt;br /&gt;
&lt;br /&gt;
    GPIO_InitTypeDef GPIOD_InitStructure;&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Mode = GPIO_Mode_OUT;     //Als Ausgang&lt;br /&gt;
    GPIOD_InitStructure.GPIO_OType = GPIO_OType_PP;    //Push-Pull Betrieb&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Pin = GPIO_Pin_15;        //Pin 15 (STM32F4-Discovery: Blaue LED)&lt;br /&gt;
    GPIOD_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;  //Kein Pull-Up oder Pull-Down Widerstand aktiviert&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Speed = GPIO_Speed_25MHz; //25MHz Update-Rate&lt;br /&gt;
    GPIO_Init(GPIOD, &amp;amp;GPIOD_InitStructure);&lt;br /&gt;
&lt;br /&gt;
    GPIO_SetBits(GPIOD, GPIO_Pin_15);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Booten aus dem SRAM==&lt;br /&gt;
STM32 Controller haben die Möglichkeit Code aus dem Flash als auch aus dem SRAM auszuführen. Um eine Anwenung per Debugger in des SRAM zu laden sind nur wenige Schritte erforderlich:&lt;br /&gt;
&lt;br /&gt;
*Um das Linkerscript für den SRAM zu verwenden geht man zu: &#039;&#039;&#039;&#039;&#039;Build options... -&amp;gt; Device&#039;&#039;&#039;&#039;&#039; dort wählt man unter &#039;&#039;&#039;&#039;&#039;Policy&#039;&#039;&#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;Use target settings&#039;&#039;&#039;&#039;&#039; aus und übernimmt die vorherigen Einstellungen, nur unter &#039;&#039;&#039;&#039;&#039;Linker script*&#039;&#039;&#039;&#039;&#039; gibt man &#039;&#039;&#039;&#039;&#039;.\stm32f407vg_sram.ld&#039;&#039;&#039;&#039;&#039; an&lt;br /&gt;
&lt;br /&gt;
*Dann muss man noch unter &#039;&#039;&#039;&#039;&#039;Debug -&amp;gt; Interfaces -&amp;gt; Settings&#039;&#039;&#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;Vector table start&#039;&#039;&#039;&#039;&#039; auf 0x20000000 ändern und &#039;&#039;&#039;&#039;&#039;Execute from RAM&#039;&#039;&#039;&#039;&#039; auswählen.&lt;br /&gt;
&lt;br /&gt;
Anschließend kann man die Anwendung ganz normal debuggen. Nach einem Reset muss die Anwenung erneut mit dem Debugger gestartet werden.&lt;br /&gt;
&lt;br /&gt;
=Fortsetzung folgt..=&lt;br /&gt;
Kritik, Wünsche usw. sind gerne erwünscht, am besten hier in den Thread posten: [http://www.mikrocontroller.net/topic/323750 Neues STM32 Tutorial]&lt;br /&gt;
&lt;br /&gt;
[[Category:ARM]]&lt;br /&gt;
[[Category:STM32]]&lt;/div&gt;</summary>
		<author><name>Avrprogger</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=STM32_-_Einstieg_mit_Em::Blocks&amp;diff=81502</id>
		<title>STM32 - Einstieg mit Em::Blocks</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=STM32_-_Einstieg_mit_Em::Blocks&amp;diff=81502"/>
		<updated>2014-02-10T15:03:13Z</updated>

		<summary type="html">&lt;p&gt;Avrprogger: vcb&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In diesem Tutorial werde ich versuchen, möglichst einfach, die ersten Schritte zur Entwicklung von STM32 Anwenungen mit der Em::Blocks IDE zu erklären. Hier soll nicht so stark auf die einzelnen Peripherie-Module der Controller eingegangen werden, sondern mehr auf die IDE und die verschieden Libraries, wie die CMSIS Library, die DSP-Library, die Standard-Peripheral-Library, die USB-Library und vllt. über Ethernet. Ich denke ein Kapitel zu FreeRTOS wird es auch geben. Auserdem steht im Vordergrund Sachen wie z.B. booten aus dem SRAM, In-Application-Programming, FPU, Core-Coupled-RAM usw. Mal sehn wie weit ich komme ;)&lt;br /&gt;
&lt;br /&gt;
==Die Entwicklungsumgebung==&lt;br /&gt;
===Hardware===&lt;br /&gt;
Zum testen der Anwendungen, benutze ich das STM32F4-Discovery Board, welches einen Debugger, Peripherie und natürlich einen STM32 Controller (STM32F407VGT6) enthält. Deshalb sind alle Beispiele hier für den STM32F407VG Controller ausgelegt, können aber meisten 1:1 auf andere Controller portiert werden. Ich werde auch möglichsts keine STM32F4-Discovery Board spezifischen Libraries verwenden, damit der Portierungs-Vorgang möglichsts einfach bleibt.&lt;br /&gt;
&lt;br /&gt;
===Software===&lt;br /&gt;
In diesem Tutorial verwende ich [http://www.emblocks.org/ Em::Blocks] als IDE. Em::Blocks ist eine kostenlose, uneingeschränkte IDE, die alle STM32 Mikrcontroller unterstützt und sehr einfach zu bedienen ist.&lt;br /&gt;
nach dem Download kann die IDE per Dialog, sehr einfach, installiert werden. Als Compiler beinhaltet Em::Blocks den &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
Die IDE unterstützt zurzeit den ST-Link, den J-Link und es gibt eine Generic-Vorlage, durch welche andere Debugger konfiguriert werden können.&lt;br /&gt;
&lt;br /&gt;
Außerdem muss noch der passende Treiber für den Debugger installiert werden. Verwendet man ein Discovery-Board muss der [http://www.st.com/web/catalog/tools/FM146/CL1984/SC724/SS1677/PF251168 ST-Link/V2]-Treiber heruntergeladen und installiert werden. (Die Installation muss evtl. als Administrator ausgeführt werden, da sonst die Installation unvollständig wird.) Nach der Installation des Treibers kann man den Debugger über die entsprechende USB Schnittstelle an den PC anschließen und es sollte die Meldung von Windows kommen, dass der richtige Treiber gefunden wurde.&lt;br /&gt;
&lt;br /&gt;
===Libraries===&lt;br /&gt;
Zum programmieren benötigt man noch die [http://www.arm.com/products/processors/cortex-m/cortex-microcontroller-software-interface-standard.php CMSIS] und die Standard-Peripheral-Library (z.B. für die F4 Controller [http://www.st.com/stonline/stappl/productcatalog/app?page=partNumberSearchPage&amp;amp;levelid=SS1577&amp;amp;parentid=1743&amp;amp;resourcetype=SW Standard-Peripheral-Library-F4]), die man am besten in einen Ordner (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\STM32&#039;&#039;&#039;&#039;&#039;) entpackt&lt;br /&gt;
&lt;br /&gt;
==Basis-Wissen zur IDE==&lt;br /&gt;
Einige Grundfunktionalitäten der IDE:&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von Dateien zum Projekt===&lt;br /&gt;
Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf &amp;lt;ProjektName&amp;gt; -&amp;gt; Add files...&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Enfernen von Dateien aus dem Projekt===&lt;br /&gt;
Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf die Datei / mehrere Dateien auswählen -&amp;gt; Remove file from project&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
Die Dateien werden lediglich aus dem Projekt entfernt und nicht von der Festplatte gelöscht.&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von Include-Pfaden===&lt;br /&gt;
Sofern die Include-Datei(en) nicht im standard Include-Ordner &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; des Projektes liegen, muss man den Pfad zum Projekt hinzufügen, damit der Compiler die Include-Dateien später auch finden kann. Man geht wie folgt vor: Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf &amp;lt;ProjektName&amp;gt; -&amp;gt; Build options... -&amp;gt; Search Directories -&amp;gt; Add&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Compilieren===&lt;br /&gt;
Entweder über das &#039;&#039;&#039;&#039;&#039;Build&#039;&#039;&#039;&#039;&#039; Menü oder über &#039;&#039;&#039;&#039;&#039;F7&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Um eine genau Ausgabe des Compiler-Aufrufes mit allen Argumenten zu bekommen, geht man im &#039;&#039;&#039;&#039;&#039;Settings&#039;&#039;&#039;&#039;&#039; Menü auf &#039;&#039;&#039;&#039;&#039;Tools...&#039;&#039;&#039;&#039;&#039; und dann auf &#039;&#039;&#039;&#039;&#039;Toolchain executables&#039;&#039;&#039;&#039;&#039;. Ganz unten, unter &#039;&#039;&#039;&#039;&#039;Logging&#039;&#039;&#039;&#039;&#039; kann man dann &#039;&#039;&#039;&#039;&#039;Full command line&#039;&#039;&#039;&#039;&#039; auswählen.&lt;br /&gt;
&lt;br /&gt;
===Debuggen===&lt;br /&gt;
*Als erstes den Debugger starten über das &#039;&#039;&#039;&#039;&#039;Debug&#039;&#039;&#039;&#039;&#039; Menü und &#039;&#039;&#039;&#039;&#039;Start/stop Debug Session&#039;&#039;&#039;&#039;&#039; oder über &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
*Danach läuft die Anwendung auf dem Controller und warten im &#039;&#039;&#039;&#039;&#039;Reset_Handler&#039;&#039;&#039;&#039;&#039; auf Einzelschritt- bzw. Run- Befehle (&#039;&#039;&#039;&#039;&#039;F5, F10, F11&#039;&#039;&#039;&#039;&#039; usw..(siehe &#039;&#039;&#039;&#039;&#039;Debug-Menü&#039;&#039;&#039;&#039;&#039; für alle Möglichkeiten))&lt;br /&gt;
&lt;br /&gt;
*Mit &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039; wird die Debug-Session auch wieder beendet&lt;br /&gt;
&lt;br /&gt;
*Unter &#039;&#039;&#039;&#039;&#039;Debug -&amp;gt; Interfaces -&amp;gt; Target settings&#039;&#039;&#039;&#039;&#039; können Eigenschaften, wie z.B &#039;&#039;&#039;&#039;&#039;Run to main()&#039;&#039;&#039;&#039;&#039; aktiviert werden.&lt;br /&gt;
&lt;br /&gt;
===Projekt als Template abspeichern===&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;File -&amp;gt; Save project as template...&#039;&#039;&#039;&#039;&#039;. Das Template erscheint dann im Projekt-Dialog unter &#039;&#039;&#039;&#039;&#039;User templates&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Das erste Projekt erstellen==&lt;br /&gt;
Hier erkläre ich, wie man am Besten (aus meiner Sicht), ein neues Projekt von Grund auf erstellt, sodass man hinterher, den Controller-Kern über die CMSIS-Library und die Peripherie über die Register steuern kann.&lt;br /&gt;
&lt;br /&gt;
===1. Projekt mit der IDE erstellen===&lt;br /&gt;
Nach der Installation der oben beschriebenen Komponenten erstellt man am besten ein Verzeichnis (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\EmBlocks&#039;&#039;&#039;&#039;&#039;), indem später alle Projekte gespeichert werden. Für Libraries kann man auch noch ein Verzeichnis (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\STM32&#039;&#039;&#039;&#039;&#039;) erstellen, wo alle Libraries gespeichert werden, die man für die Projekt brauchen.&lt;br /&gt;
&lt;br /&gt;
Als nächstes starten man EmBlocks. Bei dem ersten Start öffnet sich ein Fenster, wo verschiedene Compiler angezeigt werden, die Em::Blocks findet. Dort wählt man den &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039; aus und klickt &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039;. Nun sollte sich das Hauptfenster von Em::Blocks öffnen. Über &#039;&#039;&#039;&#039;&#039;Create a new Project&#039;&#039;&#039;&#039;&#039; oder &#039;&#039;&#039;&#039;&#039;File -&amp;gt; New -&amp;gt; Project&#039;&#039;&#039;&#039;&#039; ruft man den Projekt-Dialog auf und kann ein neues Projekt erzeugen.&lt;br /&gt;
&lt;br /&gt;
Auf der Ersten Seite wählen man den &#039;&#039;&#039;&#039;&#039;STmicro-ARM&#039;&#039;&#039;&#039;&#039; Projekt-Typ aus.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_1.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auf der nächsten Seite wird man darauf hingewiesen, dass das der entsprechende Projekt-Typ-Dialog ausgeführt wird. Hier kann man ein Häkchen bei &#039;&#039;&#039;&#039;&#039;Skip this page next time&#039;&#039;&#039;&#039;&#039; setzen und auf &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; klicken.&lt;br /&gt;
&lt;br /&gt;
Im nächsten Schritt wählen man das zuvor erstellt Verzeichnis unter &#039;&#039;&#039;&#039;&#039;Folder to create Project in&#039;&#039;&#039;&#039;&#039; aus, indem später alle Projekt gespeichert werden. Außerdem geben wir dem Projekt einen Namen (z.B. &#039;&#039;&#039;&#039;&#039;FirstProject&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_2.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danach muss man einen Compiler auswählen und bestimmen, welche Projekt-Konfigurationen erszeugt werden sollen. Unter &#039;&#039;&#039;&#039;&#039;Compiler&#039;&#039;&#039;&#039;&#039; wählt man &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039; und man kann das Häkchen bei &#039;&#039;&#039;&#039;&#039;Create &amp;quot;Release&amp;quot; configuration&#039;&#039;&#039;&#039;&#039; entfernen, da diese unnötig ist, die Debug-Konfiguration sollte eig. immer ausreichen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_3.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auf den folgenden Seite wird der Controller ausgewählt. Verwendet man ein STM32F4-Discovery Board müssen folgende Dinge gewählt werden: &#039;&#039;&#039;&#039;&#039;Cortex_M4 (F3xx - F4xx) -&amp;gt; STM32F4xx (Cortex M4 with FPU) -&amp;gt; STM32F407VG&#039;&#039;&#039;&#039;&#039;. Leider sind die Auswahl Möglichkeiten nicht ganz richtig, da auch die F3 Controller einen Cortex M4 Kern und eine FPU haben (Ist aber nicht so wichtig, ist nur eine formale Sache). Außerdem entfernt man das Häkchen bei &#039;&#039;&#039;&#039;&#039;Standard Peripherals Library&#039;&#039;&#039;&#039;&#039; (Wie man die Standard-Peripheral-Library einbindet und verwendet erkläre ich später). Man kann auch das Häkchen bei &#039;&#039;&#039;&#039;&#039;Create hex file for Realease target&#039;&#039;&#039;&#039;&#039; entfernen.&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;Stack Size&#039;&#039;&#039;&#039;&#039; und &#039;&#039;&#039;&#039;&#039;Heap Size&#039;&#039;&#039;&#039;&#039; wird die Größe von Stack und Heap festgelegt. Für eine erste Anwendung kann man die Einstellungen so lassen (Stack-Size: 0x0100 =&amp;gt; 256 Byte Stack und Heap-Size: 0x0000 =&amp;gt; kein Heap). Mit &#039;&#039;&#039;&#039;&#039;Finish&#039;&#039;&#039;&#039;&#039; ist der Projekt Dialog abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_4.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danach sollten sich zwei neue Fenster öffnen, um die Debug-Eigenschaften fest zu legen.&lt;br /&gt;
Verwendet man ein Discovery Board/ST-Link müssen die Einstellungen wie auf dem Bild gewählt werden. Über den Button &#039;&#039;&#039;&#039;&#039;Settings&#039;&#039;&#039;&#039;&#039; öffnet sich das zweite Fenster, falls sich dieses nicht schon von alleine öffnen sollte. Nach den Schließen der Fenster über &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; ist der Projekt Dialog beendet und ein neues Projekt steht zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_5_1.png|Debug Eigenschaften 1. Fenster]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_5_2.png|Debug Eigenschaften 2. Fenster]]&lt;br /&gt;
&lt;br /&gt;
===2. CMSIS-Library und Startup-Code hinzufügen===&lt;br /&gt;
Wenn man sich, nachdem man ein neues Projekt in der IDE erstellt hat, die bereits vorhandenen Dateien im Projekt ansieht, stellt man fest, das bereits ein Ordner &#039;&#039;&#039;&#039;&#039;cmsis&#039;&#039;&#039;&#039;&#039; existiert, der einige wichtige Include-Dateien der CMSIS-Library enthält. Allerdings sind das wirklich nur die wichtigsten Include-Dateien der CMSIS-Library und dazu noch, die aus einer älternen Version. Ich ziehe es deshalb vor die &amp;quot;Mini-CMSIS-Libraray&amp;quot; und die &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c/.h&#039;&#039;&#039;&#039;&#039; Dateien des Projektes durch aktuellere Versionen zu ersetzen. So ist später auch die Integration  von anderen Libraries, wie z.B. der CMSIS-DSP-Libarary einfacher.  &lt;br /&gt;
&lt;br /&gt;
Zunächst gehen man in das Projekt-Verzeichnis und löscht:&lt;br /&gt;
*Den Ordner &#039;&#039;&#039;&#039;&#039;cmsis&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Alle Dateien im Include Verzeichnis &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; im &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner&lt;br /&gt;
&lt;br /&gt;
Außerdem entfernt man auch alle gelöschten Dateien in der IDE aus dem Projekt mit &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Rechts Klick -&amp;gt; Remove file from project&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Es sollte folgende Verzeichnis Struktur überbleiben:&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_6.png|Überbleibende Dateien]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Jetzt müssen die gelöschten Dateien durch die aktuelleren ersetzt werden.&lt;br /&gt;
&lt;br /&gt;
*Dazu kopieren man den gesamten Ordner &#039;&#039;&#039;&#039;&#039;CMSIS&#039;&#039;&#039;&#039;&#039; aus dem CMSIS Download in das Projekt Verzeichnis.&lt;br /&gt;
&lt;br /&gt;
*Aus dem Standard-Peripheral-Library Download kopiert man von &#039;&#039;&#039;&#039;&#039;Libraries\CMSIS\Device\ST\STM32F4xx\Include&#039;&#039;&#039;&#039;&#039; alle Dateien in den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projekt Verzeichnisses&lt;br /&gt;
&lt;br /&gt;
*Aus der Standard-Peripheral-Library kopieren man ebenfalls von &#039;&#039;&#039;&#039;&#039;Libraries\CMSIS\Device\ST\STM32F4xx\Source\Templates&#039;&#039;&#039;&#039;&#039; die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; in den &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner des Projekts&lt;br /&gt;
&lt;br /&gt;
Anschließend müssen die neuen Dateien in der IDE dem Projekt hinzugefügt werden. Dazu benutzt man &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Rechts Klick -&amp;gt; Add files&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
*Aus dem &#039;&#039;&#039;&#039;&#039;CMSIS&#039;&#039;&#039;&#039;&#039; Ordner im Projekt Verzeichnis werden aus den Unterorder &#039;&#039;&#039;&#039;&#039;Include&#039;&#039;&#039;&#039;&#039; folgende Dateien dem Projekt hinzugefügt:&lt;br /&gt;
**arm_common_tables.h&lt;br /&gt;
**arm_const_structs.h&lt;br /&gt;
**arm_math.h&lt;br /&gt;
**core_cm4.h&lt;br /&gt;
**core_cm4_simd.h&lt;br /&gt;
**core_cmFunc.h&lt;br /&gt;
**core_cmInstr.h&lt;br /&gt;
*Alle Dateien aus den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projektes&lt;br /&gt;
*Die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; aus dem &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner&lt;br /&gt;
&lt;br /&gt;
So sollte die Struktur dann aussehen:&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_7.png|Anwenungs-Grundgerüst]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Da einige Dateien der Libraries später bearbeitet werden müssen und Schreibgeschützt sind, weise ich hier schonmal darauf hin, das der Schreibschutz in der IDE über &#039;&#039;&#039;&#039;&#039;Rechts Klick auf die Datei -&amp;gt; Properties -&amp;gt; Häkchen bei &amp;quot;File is read only&amp;quot; entfernen&#039;&#039;&#039;&#039;&#039; entfert werden kann.&lt;br /&gt;
&lt;br /&gt;
Damit die IDE die Header-Dateien der CMSIS Library auch finden kann, weil diese ja nicht im standard Include Ordner &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; liegen, muss unter &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Build Options -&amp;gt; Search Directories&#039;&#039;&#039;&#039;&#039; der Pfad &#039;&#039;&#039;&#039;&#039;CMSIS\Include&#039;&#039;&#039;&#039;&#039; hinzugefügt werden.&lt;br /&gt;
&lt;br /&gt;
Compiliert man jetzt das Projekt mit &#039;&#039;&#039;&#039;&#039;F7&#039;&#039;&#039;&#039;&#039; gibt es ein paar Fehler Meldungen, weil keine Controller-Reihe ausgewählt wurde. Ebenfalls unter &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Build Options -&amp;gt; Compiler Settings -&amp;gt; #defines&#039;&#039;&#039;&#039;&#039; wird der Define &#039;&#039;&#039;&#039;&#039;STM32F40_41xxx&#039;&#039;&#039;&#039;&#039; hinzugefügt.&lt;br /&gt;
&lt;br /&gt;
Beim erneuten Compilieren sollten sich nun keine neuen Fehler ergeben.&lt;br /&gt;
&lt;br /&gt;
===Das erste Programm===&lt;br /&gt;
Nachdem ein grundsätzliches &amp;quot;Gerüst&amp;quot; fertig ist, kann man den ersten Code schreiben.&lt;br /&gt;
main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC-&amp;gt;AHB1ENR |= RCC_AHB1ENR_GPIODEN;    //Takt für GPIO aktivieren&lt;br /&gt;
    GPIOD-&amp;gt;MODER |= GPIO_MODER_MODER15_0;   //GPIOD Pin15 als Ausgang&lt;br /&gt;
    GPIOD-&amp;gt;BSRRL |= GPIO_BSRR_BS_15;        //GPIOD Pin15 auf High ziehen&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039; wird dann der Debugger gestartet. Hat der Debugger das Projekt erfolgreich übertragen kann die Ausführung mit &#039;&#039;&#039;&#039;&#039;F5&#039;&#039;&#039;&#039;&#039; begonnen werden.&lt;br /&gt;
&lt;br /&gt;
==Takt, FPU usw.==&lt;br /&gt;
===Der Takt===&lt;br /&gt;
Jeder Controller oder Prozessor braucht einen Takt, indem er die einzelnen Maschinen-Befehle abarbeiten kann.&lt;br /&gt;
Bei den STM32 Mikrocontrollern kann dieser Takt aus verschiedenen Quellen kommen:&lt;br /&gt;
&lt;br /&gt;
1. High Speed Internal Oszillator (HSI)&lt;br /&gt;
&lt;br /&gt;
2. High Speed External Oszillator (HSE)&lt;br /&gt;
&lt;br /&gt;
3. Low Speed Internal Oszillator (LSI)&lt;br /&gt;
&lt;br /&gt;
4. Low Speed External Oszillator (LSE)&lt;br /&gt;
&lt;br /&gt;
5. Phase-Locked Loop (PLL) (generiert den Takt aus den ersten vier Taktquellen durch Teiler und Faktoren)&lt;br /&gt;
&lt;br /&gt;
Nach einem Reset wird der Controller aus der HSI Taktquelle versorgt (16MHz beim STM32F407VG). Um die voll Performance des Controllers zu erreichen muss die PLL verwendet werden, welche den Takt durch geschickte Teiler und Faktoren vervielfältigt, sodass am Ende der Controller mit der maximalen Taktfrequenz läuft. Die notwendige Initialisierung der PLL findet in der Funktion &#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; statt. Die PLL erzeugt zunächst einen Basistakt:&lt;br /&gt;
&lt;br /&gt;
PLL_VCO = (F_HSE / PLL_M) * PLL_N&lt;br /&gt;
&lt;br /&gt;
Aus diesem Takt wird dann der Takt für den Controller-Kern abgeleitet:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = PLL_VCO / PLL_P&lt;br /&gt;
&lt;br /&gt;
Und der Takt für SDIO / USB / RNG (48MHz):&lt;br /&gt;
&lt;br /&gt;
48MHz = PLL_VCO / PLL_Q&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Durch weiter Teiler werden, die Takte für die einzelnen Busse erzeugt, da diese nicht alle beliebig schnell betrieben werden dürfen.&lt;br /&gt;
&lt;br /&gt;
Genaue Angaben findet man zu dem jeweiligen Clock-System des Controllers im Reference Manual.&lt;br /&gt;
&lt;br /&gt;
Ein Blick in den &amp;quot;Kommentar-Header&amp;quot; verrät, dass von einem externen (HSE) Oszillator von 25MHz ausgegangen wird, der die PLL versorgen soll.&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((25MHz / PLL_M(25)) * PLL_N(336)) / PLL_P(2) = 168MHz&lt;br /&gt;
&lt;br /&gt;
Allerdings stimmt diese Rechnung natürlich nur, wenn wirklich ein 25MHz Quarz am Controller angeschlossen ist. Auf dem STM32F4-Discovery Board befindet sich aber nur ein 8MHz Quarz. Demnach gilt:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((8MHz / PLL_M(25)) * PLL_N(336)) / PLL_P(2) = 53.76MHz&lt;br /&gt;
&lt;br /&gt;
Der Controller läuft also nur mit 53.76MHz, wenn wie ober beschrieben ein Projekt erstellt wird. Allerdings kann dieses Problem durch ändern von den betroffen Defines behoben werden:&lt;br /&gt;
 &lt;br /&gt;
*Dazu geht man in die &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; Datei und passt zur Vollständigkeit erstmal die zum Controller passende Tabelle im &amp;quot;Kommentar-Header&amp;quot; an (Z.57f):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      HSE Frequency(Hz)                      | 8000000&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      PLL_M                                  | 8&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Danach passt man den PPL_M Define (Z.254) an:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/************************* PLL Parameters *************************************/&lt;br /&gt;
/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */&lt;br /&gt;
#define PLL_M      8&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Außerdem muss man den HSE_VALUE Define in der &#039;&#039;&#039;&#039;&#039;inc/stm32f4xx.h&#039;&#039;&#039;&#039;&#039; angepasst werden (Z.122):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#if !defined  (HSE_VALUE)&lt;br /&gt;
  #define HSE_VALUE    ((uint32_t)8000000) /*!&amp;lt; Value of the External oscillator in Hz */&lt;br /&gt;
&lt;br /&gt;
#endif /* HSE_VALUE */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine neue Berechnung zeigt:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((8MHz / PLL_M(8)) * PLL_N(336)) / PLL_P(2) = 168MHz&lt;br /&gt;
&lt;br /&gt;
Jetzt läuft der Controller mit maximaler Geschwindigkeit.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Achtung!:&lt;br /&gt;
In dem &amp;quot;Kommentar-Header&amp;quot; der &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; steht in der letzten Zeile immer:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      Require 48MHz for USB OTG FS,          | Disabled&lt;br /&gt;
*      SDIO and RNG clock                     |&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das ist jedoch falsch, weil der Takt für USB, SDIO und RNG immer mit der PLL über den Teiler PPL_Q eingestellt wird. Der Takt ist somit immer vorhanden und muss nicht extra Eingeschaltet werden. (Erspart langes Suchen, nach den entsprechenden Registern)&lt;br /&gt;
&lt;br /&gt;
===Die FPU===&lt;br /&gt;
====Allgemeines====&lt;br /&gt;
Damit die FPU richtig verwendet wird, müssen normalerweise zwei Bedingungen erfüllt sein:&lt;br /&gt;
&lt;br /&gt;
1. Der Controller muss in der Initialisierung-Funktion &#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; in &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; die FPU Hardware-seitig aktivieren&lt;br /&gt;
&lt;br /&gt;
2. Damit die FPU auch was zu tuen bekommt, müssen vom Compiler FPU-Instructions erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
Die Em::Blocks IDE verwendet standardmäßig die FPU, wenn eine Vorhanden ist. Hier wird die FPU Hardware-seitig aktiviert (&#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; Z.341):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* FPU settings ------------------------------------------------------------*/&lt;br /&gt;
  #if (__FPU_PRESENT == 1) &amp;amp;&amp;amp; (__FPU_USED == 1)&lt;br /&gt;
    SCB-&amp;gt;CPACR |= ((3UL &amp;lt;&amp;lt; 10*2)|(3UL &amp;lt;&amp;lt; 11*2));  /* set CP10 and CP11 Full Access */&lt;br /&gt;
  #endif&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
__FPU_PRESENT wird in der &#039;&#039;&#039;&#039;&#039;stm32f4xx.h&#039;&#039;&#039;&#039;&#039; definiert.&lt;br /&gt;
__FPU_USED wird von der IDE übernommen (siehe Build-Log): &#039;&#039;&#039;&#039;&#039;-D__FPU_USED&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Außerdem wird der Compiler von der IDE standardmäßig mit dem Argument &#039;&#039;&#039;&#039;&#039;-mfloat-abi=hard&#039;&#039;&#039;&#039;&#039; aufgerufen, wodurch FPU-Instructions erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
====FPU abschalten====&lt;br /&gt;
Um die FPU ab zu schalten (Mir würde jetzt nur Strom sparen als Grund einfallen) geht man wie folgt vor:&lt;br /&gt;
&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick Build options -&amp;gt; Device -&amp;gt; Policy&#039;&#039;&#039;&#039;&#039; wählt man &#039;&#039;&#039;&#039;&#039;Use target settings&#039;&#039;&#039;&#039;&#039; und über nimmt die Einstellungen, die vorher dort eingetragen waren, allerdings lässt man das Feld &#039;&#039;&#039;&#039;&#039;FP-hardware&#039;&#039;&#039;&#039;&#039; frei.&lt;br /&gt;
&lt;br /&gt;
[[Datei:fpu_1.png|FPU Abschalten Schritt 1]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;Compiler Settings -&amp;gt; Policy&#039;&#039;&#039;&#039;&#039; wählt man dann &#039;&#039;&#039;&#039;&#039;Use target options only&#039;&#039;&#039;&#039;&#039;. Dann kann man unter &#039;&#039;&#039;&#039;&#039;Categories&#039;&#039;&#039;&#039;&#039; die Option &#039;&#039;&#039;&#039;&#039;ARM FPU architecture&#039;&#039;&#039;&#039;&#039; auswählen. Dort stehen dann drei Möglichkeiten für die FPU zur Verfügung:&lt;br /&gt;
&lt;br /&gt;
1. Software-FPU-Library für Gleitkomma-Berechnung verwenden - Keine FPU-Instructions werden generiert (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=soft&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
2. Eine Mischung aus Software- und Hardware-FPU wird verwendet (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=softfp&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
3. Hardware-FPU wird für Gleitkomma-Berechnungen verwendet (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=hard&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
[[Datei:fpu_2.png|FPU Abschalten Schritt 2]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Um die FPU ab zu schalten wählt man natürlich die erste Möglichkeit.&lt;br /&gt;
Bei der 2. und 3. Möglichkeit fügt die IDE auch den Define &#039;&#039;&#039;&#039;&#039;__FPU_USED&#039;&#039;&#039;&#039;&#039; hinzu. Bei Der ersten Möglichkeit nicht. Der Code muss also nicht verändert / auskommentiert werden.&lt;br /&gt;
&lt;br /&gt;
Um die FPU wieder zu aktivieren müssen alle Schritte wieder rückgängig gemacht werden.&lt;br /&gt;
&lt;br /&gt;
Am besten ist es einfach mal alle Möglichkeiten im Einzelschritt durch zu probieren. Dann stellt man schnell fest, ob die FPU aktiviert wir oder nicht. Ein Blick in den erweiterten &#039;&#039;&#039;&#039;&#039;Build-Log&#039;&#039;&#039;&#039;&#039; gibt auch schnell Aufschluss darüber, wie der Compiler aufgerufen wird (siehe Kapitel [http://www.mikrocontroller.net/articles/STM32_-_Einstieg_mit_Em::Blocks#Compilieren Compilieren]).&lt;br /&gt;
&lt;br /&gt;
====Test Programm für die FPU====&lt;br /&gt;
Hier ein kleines Testprogramm, dass misst wie viele Taktzyklen für eine Gleitkomma-Multiplikation gebraucht werden. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define CORE_SysTickEn()    (*((u32*)0xE0001000)) = 0x40000001&lt;br /&gt;
#define CORE_SysTickDis()   (*((u32*)0xE0001000)) = 0x40000000&lt;br /&gt;
#define CORE_GetSysTick()   (*((u32*)0xE0001004))&lt;br /&gt;
&lt;br /&gt;
uint32_t t1, t2, dt;&lt;br /&gt;
float x, y, z;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    x = 53.64f;&lt;br /&gt;
    y = 0.27f;&lt;br /&gt;
&lt;br /&gt;
    CORE_SysTickEn();&lt;br /&gt;
    t1 = CORE_GetSysTick();&lt;br /&gt;
&lt;br /&gt;
    z = x * y;&lt;br /&gt;
&lt;br /&gt;
    t2 = CORE_GetSysTick();&lt;br /&gt;
    CORE_SysTickDis();&lt;br /&gt;
&lt;br /&gt;
    dt = t2 - t1;&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mein Ergebnis:&lt;br /&gt;
*Mit Hardware-FPU:  dt = 25&lt;br /&gt;
*Ohne Hardware-FPU: dt = 83&lt;br /&gt;
&lt;br /&gt;
==Einbinden der Standard Peripheral Library==&lt;br /&gt;
Um nicht immer die einzelnen Register, wie im ersten &amp;quot;bare-metal&amp;quot; Beispiel, aus dem Reference-Manual zu suchen und zu beschreiben, gibt es von ST die Standard Peripheral Library, die diese Aufgaben übernimmt und mit der sich die &amp;quot;normale/grundlegende&amp;quot; (Alles außer USB und Ethernet) Peripherie recht einfach steuern lässt. Um die Library zu verwenden erzeugt man wie oben beschrieben ein neues Grundgerüst und kopiert als erstes den Ordner &#039;&#039;&#039;&#039;&#039;Libraries\STM32F4xx_StdPeriph_Driver&#039;&#039;&#039;&#039;&#039; aus dem Standard-Peripheral-Library Download in das Projekt-Verzeichnis. Außerdem muss man die Datei &#039;&#039;&#039;&#039;&#039;Project\STM32F4xx_StdPeriph_Templates\stm32f4xx_conf.h&#039;&#039;&#039;&#039;&#039; ebenfalls aus dem Standard-Peripheral-Library Download in den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projektes kopieren. In der IDE fügt man den Include-Path &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\inc&#039;&#039;&#039;&#039;&#039; hinzufügen, wie bei der CMSIS-Library (s.o.).&lt;br /&gt;
Außerdem muss noch &#039;&#039;&#039;&#039;&#039;USE_STDPERIPH_DRIVER&#039;&#039;&#039;&#039;&#039; als Define in der IDE hinzugefügt werden (s.o.).&lt;br /&gt;
Danach fügt man die Source- und Include-Dateien aus dem Ordner &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\inc&#039;&#039;&#039;&#039;&#039; und &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\src&#039;&#039;&#039;&#039;&#039; dem Project mit &#039;&#039;&#039;&#039;&#039;&amp;lt;Project Name&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Add files&#039;&#039;&#039;&#039;&#039; hinzu, allerdings nur die, für welche auch der Controller die entsprechende Peripherie besitzt. Beim STM32F4-Discovery Board / STM32F407VG Controller dürfen also nicht folgende Dateien nicht mit hinzugefügt werden, weil diese Peripherie nur bei anderen Controller vorhanden ist:&lt;br /&gt;
&lt;br /&gt;
*stm32f4xx_dma2d.c/.h&lt;br /&gt;
*stm32f4xx_fmc.c/.h&lt;br /&gt;
*stm32f4xx_ltdc.c/.h&lt;br /&gt;
*stm32f4xx_sai.c/.h&lt;br /&gt;
&lt;br /&gt;
Daraus resultiert folgende Struktur:&lt;br /&gt;
&lt;br /&gt;
[[Datei:stdperiphlib_2.png|Header-Struktur]] [[Datei:stdperiphlib_1.png|Source-Struktur]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Anschließen kann die Standard-Peripheral-Library benutz werden.&lt;br /&gt;
main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);&lt;br /&gt;
&lt;br /&gt;
    GPIO_InitTypeDef GPIOD_InitStructure;&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Mode = GPIO_Mode_OUT;     //Als Ausgang&lt;br /&gt;
    GPIOD_InitStructure.GPIO_OType = GPIO_OType_PP;    //Push-Pull Betrieb&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Pin = GPIO_Pin_15;        //Pin 15 (STM32F4-Discovery: Blaue LED)&lt;br /&gt;
    GPIOD_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;  //Kein Pull-Up oder Pull-Down Widerstand aktiviert&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Speed = GPIO_Speed_25MHz; //25MHz Update-Rate&lt;br /&gt;
    GPIO_Init(GPIOD, &amp;amp;GPIOD_InitStructure);&lt;br /&gt;
&lt;br /&gt;
    GPIO_SetBits(GPIOD, GPIO_Pin_15);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Booten aus dem SRAM==&lt;br /&gt;
STM32 Controller haben die Möglichkeit Code aus dem Flash als auch aus dem SRAM auszuführen. Um eine Anwenung per Debugger in des SRAM zu laden sind nur wenige Schritte erforderlich:&lt;br /&gt;
&lt;br /&gt;
*Um das Linkerscript für den SRAM zu verwenden geht man zu: &#039;&#039;&#039;&#039;&#039;Build options... -&amp;gt; Device&#039;&#039;&#039;&#039;&#039; dort wählt man unter &#039;&#039;&#039;&#039;&#039;Policy&#039;&#039;&#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;Use target settings&#039;&#039;&#039;&#039;&#039; aus und übernimmt die vorherigen Einstellungen, nur unter &#039;&#039;&#039;&#039;&#039;Linker script*&#039;&#039;&#039;&#039;&#039; gibt man &#039;&#039;&#039;&#039;&#039;.\stm32f407vg_sram.ld&#039;&#039;&#039;&#039;&#039; an&lt;br /&gt;
&lt;br /&gt;
*Dann muss man noch unter &#039;&#039;&#039;&#039;&#039;Debug -&amp;gt; Interfaces -&amp;gt; Settings&#039;&#039;&#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;Vector table start&#039;&#039;&#039;&#039;&#039; auf 0x20000000 ändern und &#039;&#039;&#039;&#039;&#039;Execute from RAM&#039;&#039;&#039;&#039;&#039; auswählen.&lt;br /&gt;
&lt;br /&gt;
Anschließend kann man die Anwendung ganz normal debuggen. Nach einem Reset muss die Anwenung erneut mit dem Debugger gestartet werden.&lt;br /&gt;
&lt;br /&gt;
=Fortsetzung folgt..=&lt;br /&gt;
Kritik, Wünsche usw. sind gerne erwünscht, am besten hier in den Thread posten: [http://www.mikrocontroller.net/topic/323750 Neues STM32 Tutorial]&lt;br /&gt;
&lt;br /&gt;
[[Category:ARM]]&lt;br /&gt;
[[Category:STM32]]&lt;/div&gt;</summary>
		<author><name>Avrprogger</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=STM32_-_Einstieg_mit_Em::Blocks&amp;diff=81495</id>
		<title>STM32 - Einstieg mit Em::Blocks</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=STM32_-_Einstieg_mit_Em::Blocks&amp;diff=81495"/>
		<updated>2014-02-09T18:40:07Z</updated>

		<summary type="html">&lt;p&gt;Avrprogger: dfg&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In diesem Tutorial werde ich versuchen, möglichst einfach, die ersten Schritte zur Entwicklung von STM32 Anwenungen mit der Em::Blocks IDE zu erklären. Hier soll nicht so stark auf die einzelnen Peripherie-Module der Controller eingegangen werden, sondern mehr auf die IDE und die verschieden Libraries, wie die CMSIS Library, die DSP-Library, die Standard-Peripheral-Library, die USB-Library und vllt. über Ethernet. Ich denke ein Kapitel zu FreeRTOS wird es auch geben. Auserdem steht im Vordergrund Sachen wie z.B. booten aus dem SRAM, In-Application-Programming, FPU, Core-Coupled-RAM usw. Mal sehn wie weit ich komme ;)&lt;br /&gt;
&lt;br /&gt;
==Die Entwicklungsumgebung==&lt;br /&gt;
===Hardware===&lt;br /&gt;
Zum testen der Anwendungen, benutze ich das STM32F4-Discovery Board, welches einen Debugger, Peripherie und natürlich einen STM32 Controller (STM32F407VGT6) enthält. Deshalb sind alle Beispiele hier für den STM32F407VG Controller ausgelegt, können aber meisten 1:1 auf andere Controller portiert werden. Ich werde auch möglichsts keine STM32F4-Discovery Board spezifischen Libraries verwenden, damit der Portierungs-Vorgang möglichsts einfach bleibt.&lt;br /&gt;
&lt;br /&gt;
===Software===&lt;br /&gt;
In diesem Tutorial verwende ich [http://www.emblocks.org/ Em::Blocks] als IDE. Em::Blocks ist eine kostenlose, uneingeschränkte IDE, die alle STM32 Mikrcontroller unterstützt und sehr einfach zu bedienen ist.&lt;br /&gt;
nach dem Download kann die IDE per Dialog, sehr einfach, installiert werden. Als Compiler beinhaltet Em::Blocks den &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
Die IDE unterstützt zurzeit den ST-Link, den J-Link und es gibt eine Generic-Vorlage, durch welche andere Debugger konfiguriert werden können.&lt;br /&gt;
&lt;br /&gt;
Außerdem muss noch der passende Treiber für den Debugger installiert werden. Verwendet man ein Discovery-Board muss der [http://www.st.com/web/catalog/tools/FM146/CL1984/SC724/SS1677/PF251168 ST-Link/V2]-Treiber heruntergeladen und installiert werden. (Die Installation muss evtl. als Administrator ausgeführt werden, da sonst die Installation unvollständig wird.) Nach der Installation des Treibers kann man den Debugger über die entsprechende USB Schnittstelle an den PC anschließen und es sollte die Meldung von Windows kommen, dass der richtige Treiber gefunden wurde.&lt;br /&gt;
&lt;br /&gt;
===Libraries===&lt;br /&gt;
Zum programmieren benötigt man noch die [http://www.arm.com/products/processors/cortex-m/cortex-microcontroller-software-interface-standard.php CMSIS] und die Standard-Peripheral-Library (z.B. für die F4 Controller [http://www.st.com/stonline/stappl/productcatalog/app?page=partNumberSearchPage&amp;amp;levelid=SS1577&amp;amp;parentid=1743&amp;amp;resourcetype=SW Standard-Peripheral-Library-F4]), die man am besten in einen Ordner (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\STM32&#039;&#039;&#039;&#039;&#039;) entpackt&lt;br /&gt;
&lt;br /&gt;
==Basis-Wissen zur IDE==&lt;br /&gt;
Einige Grundfunktionalitäten der IDE:&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von Dateien zum Projekt===&lt;br /&gt;
Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf &amp;lt;ProjektName&amp;gt; -&amp;gt; Add files...&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Enfernen von Dateien aus dem Projekt===&lt;br /&gt;
Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf die Datei / mehrere Dateien auswählen -&amp;gt; Remove file from project&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
Die Dateien werden lediglich aus dem Projekt entfernt und nicht von der Festplatte gelöscht.&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von Include-Pfaden===&lt;br /&gt;
Sofern die Include-Datei(en) nicht im standard Include-Ordner &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; des Projektes liegen, muss man den Pfad zum Projekt hinzufügen, damit der Compiler die Include-Dateien später auch finden kann. Man geht wie folgt vor: Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf &amp;lt;ProjektName&amp;gt; -&amp;gt; Build options... -&amp;gt; Search Directories -&amp;gt; Add&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Compilieren===&lt;br /&gt;
Entweder über das &#039;&#039;&#039;&#039;&#039;Build&#039;&#039;&#039;&#039;&#039; Menü oder über &#039;&#039;&#039;&#039;&#039;F7&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Um eine genau Ausgabe des Compiler-Aufrufes mit allen Argumenten zu bekommen, geht man im &#039;&#039;&#039;&#039;&#039;Settings&#039;&#039;&#039;&#039;&#039; Menü auf &#039;&#039;&#039;&#039;&#039;Tools...&#039;&#039;&#039;&#039;&#039; und dann auf &#039;&#039;&#039;&#039;&#039;Toolchain executables&#039;&#039;&#039;&#039;&#039;. Ganz unten, unter &#039;&#039;&#039;&#039;&#039;Logging&#039;&#039;&#039;&#039;&#039; kann man dann &#039;&#039;&#039;&#039;&#039;Full command line&#039;&#039;&#039;&#039;&#039; auswählen.&lt;br /&gt;
&lt;br /&gt;
===Debuggen===&lt;br /&gt;
*Als erstes den Debugger starten über das &#039;&#039;&#039;&#039;&#039;Debug&#039;&#039;&#039;&#039;&#039; Menü und &#039;&#039;&#039;&#039;&#039;Start/stop Debug Session&#039;&#039;&#039;&#039;&#039; oder über &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
*Danach läuft die Anwendung auf dem Controller und warten im &#039;&#039;&#039;&#039;&#039;Reset_Handler&#039;&#039;&#039;&#039;&#039; auf Einzelschritt- bzw. Run- Befehle (&#039;&#039;&#039;&#039;&#039;F5, F10, F11&#039;&#039;&#039;&#039;&#039; usw..(siehe &#039;&#039;&#039;&#039;&#039;Debug-Menü&#039;&#039;&#039;&#039;&#039; für alle Möglichkeiten))&lt;br /&gt;
&lt;br /&gt;
*Mit &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039; wird die Debug-Session auch wieder beendet&lt;br /&gt;
&lt;br /&gt;
*Unter &#039;&#039;&#039;&#039;&#039;Debug -&amp;gt; Interfaces -&amp;gt; Target settings&#039;&#039;&#039;&#039;&#039; können Eigenschaften, wie z.B &#039;&#039;&#039;&#039;&#039;Run to main()&#039;&#039;&#039;&#039;&#039; aktiviert werden.&lt;br /&gt;
&lt;br /&gt;
===Projekt als Template abspeichern===&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;File -&amp;gt; Save project as template...&#039;&#039;&#039;&#039;&#039;. Das Template erscheint dann im Projekt-Dialog unter &#039;&#039;&#039;&#039;&#039;User templates&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Das erste Projekt erstellen==&lt;br /&gt;
Hier erkläre ich, wie man am Besten (aus meiner Sicht), ein neues Projekt von Grund auf erstellt, sodass man hinterher, den Controller-Kern über die CMSIS-Library und die Peripherie über die Register steuern kann.&lt;br /&gt;
&lt;br /&gt;
===1. Projekt mit der IDE erstellen===&lt;br /&gt;
Nach der Installation der oben beschriebenen Komponenten erstellt man am besten ein Verzeichnis (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\EmBlocks&#039;&#039;&#039;&#039;&#039;), indem später alle Projekte gespeichert werden. Für Libraries kann man auch noch ein Verzeichnis (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\STM32&#039;&#039;&#039;&#039;&#039;) erstellen, wo alle Libraries gespeichert werden, die man für die Projekt brauchen.&lt;br /&gt;
&lt;br /&gt;
Als nächstes starten man EmBlocks. Bei dem ersten Start öffnet sich ein Fenster, wo verschiedene Compiler angezeigt werden, die Em::Blocks findet. Dort wählt man den &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039; aus und klickt &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039;. Nun sollte sich das Hauptfenster von Em::Blocks öffnen. Über &#039;&#039;&#039;&#039;&#039;Create a new Project&#039;&#039;&#039;&#039;&#039; oder &#039;&#039;&#039;&#039;&#039;File -&amp;gt; New -&amp;gt; Project&#039;&#039;&#039;&#039;&#039; ruft man den Projekt-Dialog auf und kann ein neues Projekt erzeugen.&lt;br /&gt;
&lt;br /&gt;
Auf der Ersten Seite wählen man den &#039;&#039;&#039;&#039;&#039;STmicro-ARM&#039;&#039;&#039;&#039;&#039; Projekt-Typ aus.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_1.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auf der nächsten Seite wird man darauf hingewiesen, dass das der entsprechende Projekt-Typ-Dialog ausgeführt wird. Hier kann man ein Häkchen bei &#039;&#039;&#039;&#039;&#039;Skip this page next time&#039;&#039;&#039;&#039;&#039; setzen und auf &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; klicken.&lt;br /&gt;
&lt;br /&gt;
Im nächsten Schritt wählen man das zuvor erstellt Verzeichnis unter &#039;&#039;&#039;&#039;&#039;Folder to create Project in&#039;&#039;&#039;&#039;&#039; aus, indem später alle Projekt gespeichert werden. Außerdem geben wir dem Projekt einen Namen (z.B. &#039;&#039;&#039;&#039;&#039;FirstProject&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_2.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danach muss man einen Compiler auswählen und bestimmen, welche Projekt-Konfigurationen erszeugt werden sollen. Unter &#039;&#039;&#039;&#039;&#039;Compiler&#039;&#039;&#039;&#039;&#039; wählt man &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039; und man kann das Häkchen bei &#039;&#039;&#039;&#039;&#039;Create &amp;quot;Release&amp;quot; configuration&#039;&#039;&#039;&#039;&#039; entfernen, da diese unnötig ist, die Debug-Konfiguration sollte eig. immer ausreichen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_3.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auf den folgenden Seite wird der Controller ausgewählt. Verwendet man ein STM32F4-Discovery Board müssen folgende Dinge gewählt werden: &#039;&#039;&#039;&#039;&#039;Cortex_M4 (F3xx - F4xx) -&amp;gt; STM32F4xx (Cortex M4 with FPU) -&amp;gt; STM32F407VG&#039;&#039;&#039;&#039;&#039;. Leider sind die Auswahl Möglichkeiten nicht ganz richtig, da auch die F3 Controller einen Cortex M4 Kern und eine FPU haben (Ist aber nicht so wichtig, ist nur eine formale Sache). Außerdem entfernt man das Häkchen bei &#039;&#039;&#039;&#039;&#039;Standard Peripherals Library&#039;&#039;&#039;&#039;&#039; (Wie man die Standard-Peripheral-Library einbindet und verwendet erkläre ich später). Man kann auch das Häkchen bei &#039;&#039;&#039;&#039;&#039;Create hex file for Realease target&#039;&#039;&#039;&#039;&#039; entfernen.&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;Stack Size&#039;&#039;&#039;&#039;&#039; und &#039;&#039;&#039;&#039;&#039;Heap Size&#039;&#039;&#039;&#039;&#039; wird die Größe von Stack und Heap festgelegt. Für eine erste Anwendung kann man die Einstellungen so lassen (Stack-Size: 0x0100 =&amp;gt; 256 Byte Stack und Heap-Size: 0x0000 =&amp;gt; kein Heap). Mit &#039;&#039;&#039;&#039;&#039;Finish&#039;&#039;&#039;&#039;&#039; ist der Projekt Dialog abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_4.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danach sollten sich zwei neue Fenster öffnen, um die Debug-Eigenschaften fest zu legen.&lt;br /&gt;
Verwendet man ein Discovery Board/ST-Link müssen die Einstellungen wie auf dem Bild gewählt werden. Über den Button &#039;&#039;&#039;&#039;&#039;Settings&#039;&#039;&#039;&#039;&#039; öffnet sich das zweite Fenster, falls sich dieses nicht schon von alleine öffnen sollte. Nach den Schließen der Fenster über &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; ist der Projekt Dialog beendet und ein neues Projekt steht zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_5_1.png|Debug Eigenschaften 1. Fenster]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_5_2.png|Debug Eigenschaften 2. Fenster]]&lt;br /&gt;
&lt;br /&gt;
===2. CMSIS-Library und Startup-Code hinzufügen===&lt;br /&gt;
Wenn man sich, nachdem man ein neues Projekt in der IDE erstellt hat, die bereits vorhandenen Dateien im Projekt ansieht, stellt man fest, das bereits ein Ordner &#039;&#039;&#039;&#039;&#039;cmsis&#039;&#039;&#039;&#039;&#039; existiert, der einige wichtige Include-Dateien der CMSIS-Library enthält. Allerdings sind das wirklich nur die wichtigsten Include-Dateien der CMSIS-Library und dazu noch, die aus einer älternen Version. Ich ziehe es deshalb vor die &amp;quot;Mini-CMSIS-Libraray&amp;quot; und die &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c/.h&#039;&#039;&#039;&#039;&#039; Dateien des Projektes durch aktuellere Versionen zu ersetzen. So ist später auch die Integration  von anderen Libraries, wie z.B. der CMSIS-DSP-Libarary einfacher.  &lt;br /&gt;
&lt;br /&gt;
Zunächst gehen man in das Projekt-Verzeichnis und löscht:&lt;br /&gt;
*Den Ordner &#039;&#039;&#039;&#039;&#039;cmsis&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Alle Dateien im Include Verzeichnis &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; im &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner&lt;br /&gt;
&lt;br /&gt;
Außerdem entfernt man auch alle gelöschten Dateien in der IDE aus dem Projekt mit &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Rechts Klick -&amp;gt; Remove file from project&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Es sollte folgende Verzeichnis Struktur überbleiben:&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_6.png|Überbleibende Dateien]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Jetzt müssen die gelöschten Dateien durch die aktuelleren ersetzt werden.&lt;br /&gt;
&lt;br /&gt;
*Dazu kopieren man den gesamten Ordner &#039;&#039;&#039;&#039;&#039;CMSIS&#039;&#039;&#039;&#039;&#039; aus dem CMSIS Download in das Projekt Verzeichnis.&lt;br /&gt;
&lt;br /&gt;
*Aus dem Standard-Peripheral-Library Download kopiert man von &#039;&#039;&#039;&#039;&#039;Libraries\CMSIS\Device\ST\STM32F4xx\Include&#039;&#039;&#039;&#039;&#039; alle Dateien in den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projekt Verzeichnisses&lt;br /&gt;
&lt;br /&gt;
*Aus der Standard-Peripheral-Library kopieren man ebenfalls von &#039;&#039;&#039;&#039;&#039;Libraries\CMSIS\Device\ST\STM32F4xx\Source\Templates&#039;&#039;&#039;&#039;&#039; die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; in den &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner des Projekts&lt;br /&gt;
&lt;br /&gt;
Anschließend müssen die neuen Dateien in der IDE dem Projekt hinzugefügt werden. Dazu benutzt man &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Rechts Klick -&amp;gt; Add files&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
*Aus dem &#039;&#039;&#039;&#039;&#039;CMSIS&#039;&#039;&#039;&#039;&#039; Ordner im Projekt Verzeichnis werden aus den Unterorder &#039;&#039;&#039;&#039;&#039;Include&#039;&#039;&#039;&#039;&#039; folgende Dateien dem Projekt hinzugefügt:&lt;br /&gt;
**arm_common_tables.h&lt;br /&gt;
**arm_const_structs.h&lt;br /&gt;
**arm_math.h&lt;br /&gt;
**core_cm4.h&lt;br /&gt;
**core_cm4_simd.h&lt;br /&gt;
**core_cmFunc.h&lt;br /&gt;
**core_cmInstr.h&lt;br /&gt;
*Alle Dateien aus den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projektes&lt;br /&gt;
*Die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; aus dem &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner&lt;br /&gt;
&lt;br /&gt;
So sollte die Struktur dann aussehen:&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_7.png|Anwenungs-Grundgerüst]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Da einige Dateien der Libraries später bearbeitet werden müssen und Schreibgeschützt sind, weise ich hier schonmal darauf hin, das der Schreibschutz in der IDE über &#039;&#039;&#039;&#039;&#039;Rechts Klick auf die Datei -&amp;gt; Properties -&amp;gt; Häkchen bei &amp;quot;File is read only&amp;quot; entfernen&#039;&#039;&#039;&#039;&#039; entfert werden kann.&lt;br /&gt;
&lt;br /&gt;
Damit die IDE die Header-Dateien der CMSIS Library auch finden kann, weil diese ja nicht im standard Include Ordner &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; liegen, muss unter &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Build Options -&amp;gt; Search Directories&#039;&#039;&#039;&#039;&#039; der Pfad &#039;&#039;&#039;&#039;&#039;CMSIS\Include&#039;&#039;&#039;&#039;&#039; hinzugefügt werden.&lt;br /&gt;
&lt;br /&gt;
Compiliert man jetzt das Projekt mit &#039;&#039;&#039;&#039;&#039;F7&#039;&#039;&#039;&#039;&#039; gibt es ein paar Fehler Meldungen, weil keine Controller-Reihe ausgewählt wurde. Ebenfalls unter &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Build Options -&amp;gt; Compiler Settings -&amp;gt; #defines&#039;&#039;&#039;&#039;&#039; wird der Define &#039;&#039;&#039;&#039;&#039;STM32F40_41xxx&#039;&#039;&#039;&#039;&#039; hinzugefügt.&lt;br /&gt;
&lt;br /&gt;
Beim erneuten Compilieren sollten sich nun keine neuen Fehler ergeben.&lt;br /&gt;
&lt;br /&gt;
===Das erste Programm===&lt;br /&gt;
Nachdem ein grundsätzliches &amp;quot;Gerüst&amp;quot; fertig ist, kann man den ersten Code schreiben.&lt;br /&gt;
main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC-&amp;gt;AHB1ENR |= RCC_AHB1ENR_GPIODEN;    //Takt für GPIO aktivieren&lt;br /&gt;
    GPIOD-&amp;gt;MODER |= GPIO_MODER_MODER15_0;   //GPIOD Pin15 als Ausgang&lt;br /&gt;
    GPIOD-&amp;gt;BSRRL |= GPIO_BSRR_BS_15;        //GPIOD Pin15 auf High ziehen&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039; wird dann der Debugger gestartet. Hat der Debugger das Projekt erfolgreich übertragen kann die Ausführung mit &#039;&#039;&#039;&#039;&#039;F5&#039;&#039;&#039;&#039;&#039; begonnen werden.&lt;br /&gt;
&lt;br /&gt;
==Takt, FPU usw.==&lt;br /&gt;
===Der Takt===&lt;br /&gt;
Jeder Controller oder Prozessor braucht einen Takt, indem er die einzelnen Maschinen-Befehle abarbeiten kann.&lt;br /&gt;
Bei den STM32 Mikrocontrollern kann dieser Takt aus verschiedenen Quellen kommen:&lt;br /&gt;
&lt;br /&gt;
1. High Speed Internal Oszillator (HSI)&lt;br /&gt;
&lt;br /&gt;
2. High Speed External Oszillator (HSE)&lt;br /&gt;
&lt;br /&gt;
3. Low Speed Internal Oszillator (LSI)&lt;br /&gt;
&lt;br /&gt;
4. Low Speed External Oszillator (LSE)&lt;br /&gt;
&lt;br /&gt;
5. Phase-Locked Loop (PLL) (generiert den Takt aus den ersten vier Taktquellen durch Teiler und Faktoren)&lt;br /&gt;
&lt;br /&gt;
Nach einem Reset wird der Controller aus der HSI Taktquelle versorgt (16MHz beim STM32F407VG). Um die voll Performance des Controllers zu erreichen muss die PLL verwendet werden, welche den Takt durch geschickte Teiler und Faktoren vervielfältigt, sodass am Ende der Controller mit der maximalen Taktfrequenz läuft. Die notwendige Initialisierung der PLL findet in der Funktion &#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; statt. Die PLL erzeugt zunächst einen Basistakt:&lt;br /&gt;
&lt;br /&gt;
PLL_VCO = (F_HSE / PLL_M) * PLL_N&lt;br /&gt;
&lt;br /&gt;
Aus diesem Takt wird dann der Takt für den Controller-Kern abgeleitet:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = PLL_VCO / PLL_P&lt;br /&gt;
&lt;br /&gt;
Und der Takt für SDIO / USB / RNG (48MHz):&lt;br /&gt;
&lt;br /&gt;
48MHz = PLL_VCO / PLL_Q&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Durch weiter Teiler werden, die Takte für die einzelnen Busse erzeugt, da diese nicht alle beliebig schnell betrieben werden dürfen.&lt;br /&gt;
&lt;br /&gt;
Genaue Angaben findet man zu dem jeweiligen Clock-System des Controllers im Reference Manual.&lt;br /&gt;
&lt;br /&gt;
Ein Blick in den &amp;quot;Kommentar-Header&amp;quot; verrät, dass von einem externen (HSE) Oszillator von 25MHz ausgegangen wird, der die PLL versorgen soll.&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((25MHz / PLL_M(25)) * PLL_N(336)) / PLL_P(2) = 168MHz&lt;br /&gt;
&lt;br /&gt;
Allerdings stimmt diese Rechnung natürlich nur, wenn wirklich ein 25MHz Quarz am Controller angeschlossen ist. Auf dem STM32F4-Discovery Board befindet sich aber nur ein 8MHz Quarz. Demnach gilt:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((8MHz / PLL_M(25)) * PLL_N(336)) / PLL_P(2) = 53.76MHz&lt;br /&gt;
&lt;br /&gt;
Der Controller läuft also nur mit 53.76MHz, wenn wie ober beschrieben ein Projekt erstellt wird. Allerdings kann dieses Problem durch ändern von den betroffen Defines behoben werden:&lt;br /&gt;
 &lt;br /&gt;
*Dazu geht man in die &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; Datei und passt zur Vollständigkeit erstmal die zum Controller passende Tabelle im &amp;quot;Kommentar-Header&amp;quot; an (Z.57f):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      HSE Frequency(Hz)                      | 8000000&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      PLL_M                                  | 8&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Danach passt man den PPL_M Define (Z.254) an:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/************************* PLL Parameters *************************************/&lt;br /&gt;
/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */&lt;br /&gt;
#define PLL_M      8&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Außerdem muss man den HSE_VALUE Define in der &#039;&#039;&#039;&#039;&#039;inc/stm32f4xx.h&#039;&#039;&#039;&#039;&#039; angepasst werden (Z.122):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#if !defined  (HSE_VALUE)&lt;br /&gt;
  #define HSE_VALUE    ((uint32_t)8000000) /*!&amp;lt; Value of the External oscillator in Hz */&lt;br /&gt;
&lt;br /&gt;
#endif /* HSE_VALUE */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine neue Berechnung zeigt:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((8MHz / PLL_M(8)) * PLL_N(336)) / PLL_P(2) = 168MHz&lt;br /&gt;
&lt;br /&gt;
Jetzt läuft der Controller mit maximaler Geschwindigkeit.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Achtung!:&lt;br /&gt;
In dem &amp;quot;Kommentar-Header&amp;quot; der &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; steht in der letzten Zeile immer:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      Require 48MHz for USB OTG FS,          | Disabled&lt;br /&gt;
*      SDIO and RNG clock                     |&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das ist jedoch falsch, weil der Takt für USB, SDIO und RNG immer mit der PLL über den Teiler PPL_Q eingestellt wird. Der Takt ist somit immer vorhanden und muss nicht extra Eingeschaltet werden. (Erspart langes Suchen, nach den entsprechenden Registern)&lt;br /&gt;
&lt;br /&gt;
===Die FPU===&lt;br /&gt;
====Allgemeines====&lt;br /&gt;
Damit die FPU richtig verwendet wird, müssen normalerweise zwei Bedingungen erfüllt sein:&lt;br /&gt;
&lt;br /&gt;
1. Der Controller muss in der Initialisierung-Funktion &#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; in &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; die FPU Hardware-seitig aktivieren&lt;br /&gt;
&lt;br /&gt;
2. Damit die FPU auch was zu tuen bekommt, müssen vom Compiler FPU-Instructions erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
Die Em::Blocks IDE verwendet standardmäßig die FPU, wenn eine Vorhanden ist. Hier wird die FPU Hardware-seitig aktiviert (&#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; Z.341):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* FPU settings ------------------------------------------------------------*/&lt;br /&gt;
  #if (__FPU_PRESENT == 1) &amp;amp;&amp;amp; (__FPU_USED == 1)&lt;br /&gt;
    SCB-&amp;gt;CPACR |= ((3UL &amp;lt;&amp;lt; 10*2)|(3UL &amp;lt;&amp;lt; 11*2));  /* set CP10 and CP11 Full Access */&lt;br /&gt;
  #endif&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
__FPU_PRESENT wird in der &#039;&#039;&#039;&#039;&#039;stm32f4xx.h&#039;&#039;&#039;&#039;&#039; definiert.&lt;br /&gt;
__FPU_USED wird von der IDE übernommen (siehe Build-Log): &#039;&#039;&#039;&#039;&#039;-D__FPU_USED&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Außerdem wird der Compiler von der IDE standardmäßig mit dem Argument &#039;&#039;&#039;&#039;&#039;-mfloat-abi=hard&#039;&#039;&#039;&#039;&#039; aufgerufen, wodurch FPU-Instructions erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
====FPU abschalten====&lt;br /&gt;
Um die FPU ab zu schalten (Mir würde jetzt nur Strom sparen als Grund einfallen) geht man wie folgt vor:&lt;br /&gt;
&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick Build options -&amp;gt; Device -&amp;gt; Policy&#039;&#039;&#039;&#039;&#039; wählt man &#039;&#039;&#039;&#039;&#039;Use target settings&#039;&#039;&#039;&#039;&#039; und über nimmt die Einstellungen, die vorher dort eingetragen waren, allerdings lässt man das Feld &#039;&#039;&#039;&#039;&#039;FP-hardware&#039;&#039;&#039;&#039;&#039; frei.&lt;br /&gt;
&lt;br /&gt;
[[Datei:fpu_1.png|FPU Abschalten Schritt 1]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;Compiler Settings -&amp;gt; Policy&#039;&#039;&#039;&#039;&#039; wählt man dann &#039;&#039;&#039;&#039;&#039;Use target options only&#039;&#039;&#039;&#039;&#039;. Dann kann man unter &#039;&#039;&#039;&#039;&#039;Categories&#039;&#039;&#039;&#039;&#039; die Option &#039;&#039;&#039;&#039;&#039;ARM FPU architecture&#039;&#039;&#039;&#039;&#039; auswählen. Dort stehen dann drei Möglichkeiten für die FPU zur Verfügung:&lt;br /&gt;
&lt;br /&gt;
1. Software-FPU-Library für Gleitkomma-Berechnung verwenden - Keine FPU-Instructions werden generiert (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=soft&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
2. Eine Mischung aus Software- und Hardware-FPU wird verwendet (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=softfp&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
3. Hardware-FPU wird für Gleitkomma-Berechnungen verwendet (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=hard&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
[[Datei:fpu_2.png|FPU Abschalten Schritt 2]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Um die FPU ab zu schalten wählt man natürlich die erste Möglichkeit.&lt;br /&gt;
Bei der 2. und 3. Möglichkeit fügt die IDE auch den Define &#039;&#039;&#039;&#039;&#039;__FPU_USED&#039;&#039;&#039;&#039;&#039; hinzu. Bei Der ersten Möglichkeit nicht. Der Code muss also nicht verändert / auskommentiert werden.&lt;br /&gt;
&lt;br /&gt;
Um die FPU wieder zu aktivieren müssen alle Schritte wieder rückgängig gemacht werden.&lt;br /&gt;
&lt;br /&gt;
Am besten ist es einfach mal alle Möglichkeiten im Einzelschritt durch zu probieren. Dann stellt man schnell fest, ob die FPU aktiviert wir oder nicht. Ein Blick in den erweiterten &#039;&#039;&#039;&#039;&#039;Build-Log&#039;&#039;&#039;&#039;&#039; gibt auch schnell Aufschluss darüber, wie der Compiler aufgerufen wird (siehe Kapitel [http://www.mikrocontroller.net/articles/STM32_-_Einstieg_mit_Em::Blocks#Compilieren Compilieren]).&lt;br /&gt;
&lt;br /&gt;
====Test Programm für die FPU====&lt;br /&gt;
Hier ein kleines Testprogramm, dass misst wie viele Taktzyklen für eine Gleitkomma-Multiplikation gebraucht werden. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define CORE_SysTickEn()    (*((u32*)0xE0001000)) = 0x40000001&lt;br /&gt;
#define CORE_SysTickDis()   (*((u32*)0xE0001000)) = 0x40000000&lt;br /&gt;
#define CORE_GetSysTick()   (*((u32*)0xE0001004))&lt;br /&gt;
&lt;br /&gt;
uint32_t t1, t2, dt;&lt;br /&gt;
float x, y, z;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    x = 53.64f;&lt;br /&gt;
    y = 0.27f;&lt;br /&gt;
&lt;br /&gt;
    CORE_SysTickEn();&lt;br /&gt;
    t1 = CORE_GetSysTick();&lt;br /&gt;
&lt;br /&gt;
    z = x * y;&lt;br /&gt;
&lt;br /&gt;
    t2 = CORE_GetSysTick();&lt;br /&gt;
    CORE_SysTickDis();&lt;br /&gt;
&lt;br /&gt;
    dt = t2 - t1;&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mein Ergebnis:&lt;br /&gt;
*Mit Hardware-FPU:  dt = 25&lt;br /&gt;
*Ohne Hardware-FPU: dt = 83&lt;br /&gt;
&lt;br /&gt;
==Einbinden der Standard Peripheral Library==&lt;br /&gt;
Um nicht immer die einzelnen Register, wie im ersten &amp;quot;bare-metal&amp;quot; Beispiel, aus dem Reference-Manual zu suchen und zu beschreiben, gibt es von ST die Standard Peripheral Library, die diese Aufgaben übernimmt und mit der sich die &amp;quot;normale/grundlegende&amp;quot; (Alles außer USB und Ethernet) Peripherie recht einfach steuern lässt. Um die Library zu verwenden erzeugt man wie oben beschrieben ein neues Grundgerüst und kopiert als erstes den Ordner &#039;&#039;&#039;&#039;&#039;Libraries\STM32F4xx_StdPeriph_Driver&#039;&#039;&#039;&#039;&#039; aus dem Standard-Peripheral-Library Download in das Projekt-Verzeichnis. Außerdem muss man die Datei &#039;&#039;&#039;&#039;&#039;Project\STM32F4xx_StdPeriph_Templates\stm32f4xx_conf.h&#039;&#039;&#039;&#039;&#039; ebenfalls aus dem Standard-Peripheral-Library Download in den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projektes kopieren. In der IDE fügt man den Include-Path &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\inc&#039;&#039;&#039;&#039;&#039; hinzufügen, wie bei der CMSIS-Library (s.o.).&lt;br /&gt;
Außerdem muss noch &#039;&#039;&#039;&#039;&#039;USE_STDPERIPH_DRIVER&#039;&#039;&#039;&#039;&#039; als Define in der IDE hinzugefügt werden (s.o.).&lt;br /&gt;
Danach fügt man die Source- und Include-Dateien aus dem Ordner &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\inc&#039;&#039;&#039;&#039;&#039; und &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\src&#039;&#039;&#039;&#039;&#039; dem Project mit &#039;&#039;&#039;&#039;&#039;&amp;lt;Project Name&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Add files&#039;&#039;&#039;&#039;&#039; hinzu, allerdings nur die, für welche auch der Controller die entsprechende Peripherie besitzt. Beim STM32F4-Discovery Board / STM32F407VG Controller dürfen also nicht folgende Dateien nicht mit hinzugefügt werden, weil diese Peripherie nur bei anderen Controller vorhanden ist:&lt;br /&gt;
&lt;br /&gt;
*stm32f4xx_dma2d.c/.h&lt;br /&gt;
*stm32f4xx_fmc.c/.h&lt;br /&gt;
*stm32f4xx_ltdc.c/.h&lt;br /&gt;
*stm32f4xx_sai.c/.h&lt;br /&gt;
&lt;br /&gt;
Daraus resultiert folgende Struktur:&lt;br /&gt;
&lt;br /&gt;
[[Datei:stdperiphlib_2.png|Header-Struktur]] [[Datei:stdperiphlib_1.png|Source-Struktur]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Anschließen kann die Standard-Peripheral-Library benutz werden.&lt;br /&gt;
main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);&lt;br /&gt;
&lt;br /&gt;
    GPIO_InitTypeDef GPIOD_InitStructure;&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Mode = GPIO_Mode_OUT;&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Pin = GPIO_Pin_15;&lt;br /&gt;
    GPIO_Init(GPIOD, &amp;amp;GPIOD_InitStructure);&lt;br /&gt;
&lt;br /&gt;
    GPIO_SetBits(GPIOD, GPIO_Pin_15);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Booten aus dem SRAM==&lt;br /&gt;
STM32 Controller haben die Möglichkeit Code aus dem Flash als auch aus dem SRAM auszuführen. Um eine Anwenung per Debugger in des SRAM zu laden sind nur wenige Schritte erforderlich:&lt;br /&gt;
&lt;br /&gt;
*Um das Linkerscript für den SRAM zu verwenden geht man zu: &#039;&#039;&#039;&#039;&#039;Build options... -&amp;gt; Device&#039;&#039;&#039;&#039;&#039; dort wählt man unter &#039;&#039;&#039;&#039;&#039;Policy&#039;&#039;&#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;Use target settings&#039;&#039;&#039;&#039;&#039; aus und übernimmt die vorherigen Einstellungen, nur unter &#039;&#039;&#039;&#039;&#039;Linker script*&#039;&#039;&#039;&#039;&#039; gibt man &#039;&#039;&#039;&#039;&#039;.\stm32f407vg_sram.ld&#039;&#039;&#039;&#039;&#039; an&lt;br /&gt;
&lt;br /&gt;
*Dann muss man noch unter &#039;&#039;&#039;&#039;&#039;Debug -&amp;gt; Interfaces -&amp;gt; Settings&#039;&#039;&#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;Vector table start&#039;&#039;&#039;&#039;&#039; auf 0x20000000 ändern und &#039;&#039;&#039;&#039;&#039;Execute from RAM&#039;&#039;&#039;&#039;&#039; auswählen.&lt;br /&gt;
&lt;br /&gt;
Anschließend kann man die Anwendung ganz normal debuggen. Nach einem Reset muss die Anwenung erneut mit dem Debugger gestartet werden.&lt;br /&gt;
&lt;br /&gt;
=Fortsetzung folgt..=&lt;br /&gt;
Kritik, Wünsche usw. sind gerne erwünscht, am besten hier in den Thread posten: [http://www.mikrocontroller.net/topic/323750 Neues STM32 Tutorial]&lt;br /&gt;
&lt;br /&gt;
[[Category:ARM]]&lt;br /&gt;
[[Category:STM32]]&lt;/div&gt;</summary>
		<author><name>Avrprogger</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=STM32_-_Einstieg_mit_Em::Blocks&amp;diff=81494</id>
		<title>STM32 - Einstieg mit Em::Blocks</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=STM32_-_Einstieg_mit_Em::Blocks&amp;diff=81494"/>
		<updated>2014-02-09T18:39:39Z</updated>

		<summary type="html">&lt;p&gt;Avrprogger: fdg&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In diesem Tutorial werde ich versuchen, möglichst einfach, die ersten Schritte zur Entwicklung von STM32 Anwenungen mit der Em::Blocks IDE zu erklären. Hier soll nicht so stark auf die einzelnen Peripherie-Module der Controller eingegangen werden, sondern mehr auf die IDE und die verschieden Libraries, wie die CMSIS Library, die DSP-Library, die Standard-Peripheral-Library, die USB-Library und vllt. über Ethernet. Ich denke ein Kapitel zu FreeRTOS wird es auch geben. Auserdem steht im Vordergrund Sachen wie z.B. booten aus dem SRAM, In-Application-Programming, FPU, Core-Coupled-RAM usw. Mal sehn wie weit ich komme ;)&lt;br /&gt;
&lt;br /&gt;
==Die Entwicklungsumgebung==&lt;br /&gt;
===Hardware===&lt;br /&gt;
Zum testen der Anwendungen, benutze ich das STM32F4-Discovery Board, welches einen Debugger, Peripherie und natürlich einen STM32 Controller (STM32F407VGT6) enthält. Deshalb sind alle Beispiele hier für den STM32F407VG Controller ausgelegt, können aber meisten 1:1 auf andere Controller portiert werden. Ich werde auch möglichsts keine STM32F4-Discovery Board spezifischen Libraries verwenden, damit der Portierungs-Vorgang möglichsts einfach bleibt.&lt;br /&gt;
&lt;br /&gt;
===Software===&lt;br /&gt;
In diesem Tutorial verwende ich [http://www.emblocks.org/ Em::Blocks] als IDE. Em::Blocks ist eine kostenlose, uneingeschränkte IDE, die alle STM32 Mikrcontroller unterstützt und sehr einfach zu bedienen ist.&lt;br /&gt;
nach dem Download kann die IDE per Dialog, sehr einfach, installiert werden. Als Compiler beinhaltet Em::Blocks den &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
Die IDE unterstützt zurzeit den ST-Link, den J-Link und es gibt eine Generic-Vorlage, durch welche andere Debugger konfiguriert werden können.&lt;br /&gt;
&lt;br /&gt;
Außerdem muss noch der passende Treiber für den Debugger installiert werden. Verwendet man ein Discovery-Board muss der [http://www.st.com/web/catalog/tools/FM146/CL1984/SC724/SS1677/PF251168 ST-Link/V2]-Treiber heruntergeladen und installiert werden. (Die Installation muss evtl. als Administrator ausgeführt werden, da sonst die Installation unvollständig wird.) Nach der Installation des Treibers kann man den Debugger über die entsprechende USB Schnittstelle an den PC anschließen und es sollte die Meldung von Windows kommen, dass der richtige Treiber gefunden wurde.&lt;br /&gt;
&lt;br /&gt;
===Libraries===&lt;br /&gt;
Zum programmieren benötigt man noch die [http://www.arm.com/products/processors/cortex-m/cortex-microcontroller-software-interface-standard.php CMSIS] und die Standard-Peripheral-Library (z.B. für die F4 Controller [http://www.st.com/stonline/stappl/productcatalog/app?page=partNumberSearchPage&amp;amp;levelid=SS1577&amp;amp;parentid=1743&amp;amp;resourcetype=SW Standard-Peripheral-Library-F4]), die man am besten in einen Ordner (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\STM32&#039;&#039;&#039;&#039;&#039;) entpackt&lt;br /&gt;
&lt;br /&gt;
==Basis-Wissen zur IDE==&lt;br /&gt;
Einige Grundfunktionalitäten der IDE:&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von Dateien zum Projekt===&lt;br /&gt;
Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf &amp;lt;ProjektName&amp;gt; -&amp;gt; Add files...&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Enfernen von Dateien aus dem Projekt===&lt;br /&gt;
Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf die Datei / mehrere Dateien auswählen -&amp;gt; Remove file from project&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
Die Dateien werden lediglich aus dem Projekt entfernt und nicht von der Festplatte gelöscht.&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von Include-Pfaden===&lt;br /&gt;
Sofern die Include-Datei(en) nicht im standard Include-Ordner &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; des Projektes liegen, muss man den Pfad zum Projekt hinzufügen, damit der Compiler die Include-Dateien später auch finden kann. Man geht wie folgt vor: Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf &amp;lt;ProjektName&amp;gt; -&amp;gt; Build options... -&amp;gt; Search Directories -&amp;gt; Add&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Compilieren===&lt;br /&gt;
Entweder über das &#039;&#039;&#039;&#039;&#039;Build&#039;&#039;&#039;&#039;&#039; Menü oder über &#039;&#039;&#039;&#039;&#039;F7&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Um eine genau Ausgabe des Compiler-Aufrufes mit allen Argumenten zu bekommen, geht man im &#039;&#039;&#039;&#039;&#039;Settings&#039;&#039;&#039;&#039;&#039; Menü auf &#039;&#039;&#039;&#039;&#039;Tools...&#039;&#039;&#039;&#039;&#039; und dann auf &#039;&#039;&#039;&#039;&#039;Toolchain executables&#039;&#039;&#039;&#039;&#039;. Ganz unten, unter &#039;&#039;&#039;&#039;&#039;Logging&#039;&#039;&#039;&#039;&#039; kann man dann &#039;&#039;&#039;&#039;&#039;Full command line&#039;&#039;&#039;&#039;&#039; auswählen.&lt;br /&gt;
&lt;br /&gt;
===Debuggen===&lt;br /&gt;
*Als erstes den Debugger starten über das &#039;&#039;&#039;&#039;&#039;Debug&#039;&#039;&#039;&#039;&#039; Menü und &#039;&#039;&#039;&#039;&#039;Start/stop Debug Session&#039;&#039;&#039;&#039;&#039; oder über &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
*Danach läuft die Anwendung auf dem Controller und warten im &#039;&#039;&#039;&#039;&#039;Reset_Handler&#039;&#039;&#039;&#039;&#039; auf Einzelschritt- bzw. Run- Befehle (&#039;&#039;&#039;&#039;&#039;F5, F10, F11&#039;&#039;&#039;&#039;&#039; usw..(siehe &#039;&#039;&#039;&#039;&#039;Debug-Menü&#039;&#039;&#039;&#039;&#039; für alle Möglichkeiten))&lt;br /&gt;
&lt;br /&gt;
*Mit &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039; wird die Debug-Session auch wieder beendet&lt;br /&gt;
&lt;br /&gt;
*Unter &#039;&#039;&#039;&#039;&#039;Debug -&amp;gt; Interfaces -&amp;gt; Target settings&#039;&#039;&#039;&#039;&#039; können Eigenschaften, wie z.B &#039;&#039;&#039;&#039;&#039;Run to main()&#039;&#039;&#039;&#039;&#039; aktiviert werden.&lt;br /&gt;
&lt;br /&gt;
===Projekt als Template abspeichern===&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;File -&amp;gt; Save project as template...&#039;&#039;&#039;&#039;&#039;. Das Template erscheint dann im Projekt-Dialog unter &#039;&#039;&#039;&#039;&#039;User templates&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Das erste Projekt erstellen==&lt;br /&gt;
Hier erkläre ich, wie man am Besten (aus meiner Sicht), ein neues Projekt von Grund auf erstellt, sodass man hinterher, den Controller-Kern über die CMSIS-Library und die Peripherie über die Register steuern kann.&lt;br /&gt;
&lt;br /&gt;
===1. Projekt mit der IDE erstellen===&lt;br /&gt;
Nach der Installation der oben beschriebenen Komponenten erstellt man am besten ein Verzeichnis (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\EmBlocks&#039;&#039;&#039;&#039;&#039;), indem später alle Projekte gespeichert werden. Für Libraries kann man auch noch ein Verzeichnis (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\STM32&#039;&#039;&#039;&#039;&#039;) erstellen, wo alle Libraries gespeichert werden, die man für die Projekt brauchen.&lt;br /&gt;
&lt;br /&gt;
Als nächstes starten man EmBlocks. Bei dem ersten Start öffnet sich ein Fenster, wo verschiedene Compiler angezeigt werden, die Em::Blocks findet. Dort wählt man den &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039; aus und klickt &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039;. Nun sollte sich das Hauptfenster von Em::Blocks öffnen. Über &#039;&#039;&#039;&#039;&#039;Create a new Project&#039;&#039;&#039;&#039;&#039; oder &#039;&#039;&#039;&#039;&#039;File -&amp;gt; New -&amp;gt; Project&#039;&#039;&#039;&#039;&#039; ruft man den Projekt-Dialog auf und kann ein neues Projekt erzeugen.&lt;br /&gt;
&lt;br /&gt;
Auf der Ersten Seite wählen man den &#039;&#039;&#039;&#039;&#039;STmicro-ARM&#039;&#039;&#039;&#039;&#039; Projekt-Typ aus.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_1.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auf der nächsten Seite wird man darauf hingewiesen, dass das der entsprechende Projekt-Typ-Dialog ausgeführt wird. Hier kann man ein Häkchen bei &#039;&#039;&#039;&#039;&#039;Skip this page next time&#039;&#039;&#039;&#039;&#039; setzen und auf &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; klicken.&lt;br /&gt;
&lt;br /&gt;
Im nächsten Schritt wählen man das zuvor erstellt Verzeichnis unter &#039;&#039;&#039;&#039;&#039;Folder to create Project in&#039;&#039;&#039;&#039;&#039; aus, indem später alle Projekt gespeichert werden. Außerdem geben wir dem Projekt einen Namen (z.B. &#039;&#039;&#039;&#039;&#039;FirstProject&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_2.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danach muss man einen Compiler auswählen und bestimmen, welche Projekt-Konfigurationen erszeugt werden sollen. Unter &#039;&#039;&#039;&#039;&#039;Compiler&#039;&#039;&#039;&#039;&#039; wählt man &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039; und man kann das Häkchen bei &#039;&#039;&#039;&#039;&#039;Create &amp;quot;Release&amp;quot; configuration&#039;&#039;&#039;&#039;&#039; entfernen, da diese unnötig ist, die Debug-Konfiguration sollte eig. immer ausreichen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_3.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auf den folgenden Seite wird der Controller ausgewählt. Verwendet man ein STM32F4-Discovery Board müssen folgende Dinge gewählt werden: &#039;&#039;&#039;&#039;&#039;Cortex_M4 (F3xx - F4xx) -&amp;gt; STM32F4xx (Cortex M4 with FPU) -&amp;gt; STM32F407VG&#039;&#039;&#039;&#039;&#039;. Leider sind die Auswahl Möglichkeiten nicht ganz richtig, da auch die F3 Controller einen Cortex M4 Kern und eine FPU haben (Ist aber nicht so wichtig, ist nur eine formale Sache). Außerdem entfernt man das Häkchen bei &#039;&#039;&#039;&#039;&#039;Standard Peripherals Library&#039;&#039;&#039;&#039;&#039; (Wie man die Standard-Peripheral-Library einbindet und verwendet erkläre ich später). Man kann auch das Häkchen bei &#039;&#039;&#039;&#039;&#039;Create hex file for Realease target&#039;&#039;&#039;&#039;&#039; entfernen.&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;Stack Size&#039;&#039;&#039;&#039;&#039; und &#039;&#039;&#039;&#039;&#039;Heap Size&#039;&#039;&#039;&#039;&#039; wird die Größe von Stack und Heap festgelegt. Für eine erste Anwendung kann man die Einstellungen so lassen (Stack-Size: 0x0100 =&amp;gt; 256 Byte Stack und Heap-Size: 0x0000 =&amp;gt; kein Heap). Mit &#039;&#039;&#039;&#039;&#039;Finish&#039;&#039;&#039;&#039;&#039; ist der Projekt Dialog abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_4.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danach sollten sich zwei neue Fenster öffnen, um die Debug-Eigenschaften fest zu legen.&lt;br /&gt;
Verwendet man ein Discovery Board/ST-Link müssen die Einstellungen wie auf dem Bild gewählt werden. Über den Button &#039;&#039;&#039;&#039;&#039;Settings&#039;&#039;&#039;&#039;&#039; öffnet sich das zweite Fenster, falls sich dieses nicht schon von alleine öffnen sollte. Nach den Schließen der Fenster über &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; ist der Projekt Dialog beendet und ein neues Projekt steht zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_5_1.png|Debug Eigenschaften 1. Fenster]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_5_2.png|Debug Eigenschaften 2. Fenster]]&lt;br /&gt;
&lt;br /&gt;
===2. CMSIS-Library und Startup-Code hinzufügen===&lt;br /&gt;
Wenn man sich, nachdem man ein neues Projekt in der IDE erstellt hat, die bereits vorhandenen Dateien im Projekt ansieht, stellt man fest, das bereits ein Ordner &#039;&#039;&#039;&#039;&#039;cmsis&#039;&#039;&#039;&#039;&#039; existiert, der einige wichtige Include-Dateien der CMSIS-Library enthält. Allerdings sind das wirklich nur die wichtigsten Include-Dateien der CMSIS-Library und dazu noch, die aus einer älternen Version. Ich ziehe es deshalb vor die &amp;quot;Mini-CMSIS-Libraray&amp;quot; und die &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c/.h&#039;&#039;&#039;&#039;&#039; Dateien des Projektes durch aktuellere Versionen zu ersetzen. So ist später auch die Integration  von anderen Libraries, wie z.B. der CMSIS-DSP-Libarary einfacher.  &lt;br /&gt;
&lt;br /&gt;
Zunächst gehen man in das Projekt-Verzeichnis und löscht:&lt;br /&gt;
*Den Ordner &#039;&#039;&#039;&#039;&#039;cmsis&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Alle Dateien im Include Verzeichnis &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; im &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner&lt;br /&gt;
&lt;br /&gt;
Außerdem entfernt man auch alle gelöschten Dateien in der IDE aus dem Projekt mit &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Rechts Klick -&amp;gt; Remove file from project&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Es sollte folgende Verzeichnis Struktur überbleiben:&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_6.png|Überbleibende Dateien]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Jetzt müssen die gelöschten Dateien durch die aktuelleren ersetzt werden.&lt;br /&gt;
&lt;br /&gt;
*Dazu kopieren man den gesamten Ordner &#039;&#039;&#039;&#039;&#039;CMSIS&#039;&#039;&#039;&#039;&#039; aus dem CMSIS Download in das Projekt Verzeichnis.&lt;br /&gt;
&lt;br /&gt;
*Aus dem Standard-Peripheral-Library Download kopiert man von &#039;&#039;&#039;&#039;&#039;Libraries\CMSIS\Device\ST\STM32F4xx\Include&#039;&#039;&#039;&#039;&#039; alle Dateien in den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projekt Verzeichnisses&lt;br /&gt;
&lt;br /&gt;
*Aus der Standard-Peripheral-Library kopieren man ebenfalls von &#039;&#039;&#039;&#039;&#039;Libraries\CMSIS\Device\ST\STM32F4xx\Source\Templates&#039;&#039;&#039;&#039;&#039; die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; in den &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner des Projekts&lt;br /&gt;
&lt;br /&gt;
Anschließend müssen die neuen Dateien in der IDE dem Projekt hinzugefügt werden. Dazu benutzt man &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Rechts Klick -&amp;gt; Add files&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
*Aus dem &#039;&#039;&#039;&#039;&#039;CMSIS&#039;&#039;&#039;&#039;&#039; Ordner im Projekt Verzeichnis werden aus den Unterorder &#039;&#039;&#039;&#039;&#039;Include&#039;&#039;&#039;&#039;&#039; folgende Dateien dem Projekt hinzugefügt:&lt;br /&gt;
**arm_common_tables.h&lt;br /&gt;
**arm_const_structs.h&lt;br /&gt;
**arm_math.h&lt;br /&gt;
**core_cm4.h&lt;br /&gt;
**core_cm4_simd.h&lt;br /&gt;
**core_cmFunc.h&lt;br /&gt;
**core_cmInstr.h&lt;br /&gt;
*Alle Dateien aus den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projektes&lt;br /&gt;
*Die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; aus dem &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner&lt;br /&gt;
&lt;br /&gt;
So sollte die Struktur dann aussehen:&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_7.png|Anwenungs-Grundgerüst]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Da einige Dateien der Libraries später bearbeitet werden müssen und Schreibgeschützt sind, weise ich hier schonmal darauf hin, das der Schreibschutz in der IDE über &#039;&#039;&#039;&#039;&#039;Rechts Klick auf die Datei -&amp;gt; Properties -&amp;gt; Häkchen bei &amp;quot;File is read only&amp;quot; entfernen&#039;&#039;&#039;&#039;&#039; entfert werden kann.&lt;br /&gt;
&lt;br /&gt;
Damit die IDE die Header-Dateien der CMSIS Library auch finden kann, weil diese ja nicht im standard Include Ordner &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; liegen, muss unter &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Build Options -&amp;gt; Search Directories&#039;&#039;&#039;&#039;&#039; der Pfad &#039;&#039;&#039;&#039;&#039;CMSIS\Include&#039;&#039;&#039;&#039;&#039; hinzugefügt werden.&lt;br /&gt;
&lt;br /&gt;
Compiliert man jetzt das Projekt mit &#039;&#039;&#039;&#039;&#039;F7&#039;&#039;&#039;&#039;&#039; gibt es ein paar Fehler Meldungen, weil keine Controller-Reihe ausgewählt wurde. Ebenfalls unter &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Build Options -&amp;gt; Compiler Settings -&amp;gt; #defines&#039;&#039;&#039;&#039;&#039; wird der Define &#039;&#039;&#039;&#039;&#039;STM32F40_41xxx&#039;&#039;&#039;&#039;&#039; hinzugefügt.&lt;br /&gt;
&lt;br /&gt;
Beim erneuten Compilieren sollten sich nun keine neuen Fehler ergeben.&lt;br /&gt;
&lt;br /&gt;
===Das erste Programm===&lt;br /&gt;
Nachdem ein grundsätzliches &amp;quot;Gerüst&amp;quot; fertig ist, kann man den ersten Code schreiben.&lt;br /&gt;
main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC-&amp;gt;AHB1ENR |= RCC_AHB1ENR_GPIODEN;    //Takt für GPIO aktivieren&lt;br /&gt;
    GPIOD-&amp;gt;MODER |= GPIO_MODER_MODER15_0;   //GPIOD Pin15 als Ausgang&lt;br /&gt;
    GPIOD-&amp;gt;BSRRL |= GPIO_BSRR_BS_15;        //GPIOD Pin15 auf High ziehen&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Download: [[Datei:FirstProject.zip]]&lt;br /&gt;
&lt;br /&gt;
Mit &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039; wird dann der Debugger gestartet. Hat der Debugger das Projekt erfolgreich übertragen kann die Ausführung mit &#039;&#039;&#039;&#039;&#039;F5&#039;&#039;&#039;&#039;&#039; begonnen werden.&lt;br /&gt;
&lt;br /&gt;
==Takt, FPU usw.==&lt;br /&gt;
===Der Takt===&lt;br /&gt;
Jeder Controller oder Prozessor braucht einen Takt, indem er die einzelnen Maschinen-Befehle abarbeiten kann.&lt;br /&gt;
Bei den STM32 Mikrocontrollern kann dieser Takt aus verschiedenen Quellen kommen:&lt;br /&gt;
&lt;br /&gt;
1. High Speed Internal Oszillator (HSI)&lt;br /&gt;
&lt;br /&gt;
2. High Speed External Oszillator (HSE)&lt;br /&gt;
&lt;br /&gt;
3. Low Speed Internal Oszillator (LSI)&lt;br /&gt;
&lt;br /&gt;
4. Low Speed External Oszillator (LSE)&lt;br /&gt;
&lt;br /&gt;
5. Phase-Locked Loop (PLL) (generiert den Takt aus den ersten vier Taktquellen durch Teiler und Faktoren)&lt;br /&gt;
&lt;br /&gt;
Nach einem Reset wird der Controller aus der HSI Taktquelle versorgt (16MHz beim STM32F407VG). Um die voll Performance des Controllers zu erreichen muss die PLL verwendet werden, welche den Takt durch geschickte Teiler und Faktoren vervielfältigt, sodass am Ende der Controller mit der maximalen Taktfrequenz läuft. Die notwendige Initialisierung der PLL findet in der Funktion &#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; statt. Die PLL erzeugt zunächst einen Basistakt:&lt;br /&gt;
&lt;br /&gt;
PLL_VCO = (F_HSE / PLL_M) * PLL_N&lt;br /&gt;
&lt;br /&gt;
Aus diesem Takt wird dann der Takt für den Controller-Kern abgeleitet:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = PLL_VCO / PLL_P&lt;br /&gt;
&lt;br /&gt;
Und der Takt für SDIO / USB / RNG (48MHz):&lt;br /&gt;
&lt;br /&gt;
48MHz = PLL_VCO / PLL_Q&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Durch weiter Teiler werden, die Takte für die einzelnen Busse erzeugt, da diese nicht alle beliebig schnell betrieben werden dürfen.&lt;br /&gt;
&lt;br /&gt;
Genaue Angaben findet man zu dem jeweiligen Clock-System des Controllers im Reference Manual.&lt;br /&gt;
&lt;br /&gt;
Ein Blick in den &amp;quot;Kommentar-Header&amp;quot; verrät, dass von einem externen (HSE) Oszillator von 25MHz ausgegangen wird, der die PLL versorgen soll.&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((25MHz / PLL_M(25)) * PLL_N(336)) / PLL_P(2) = 168MHz&lt;br /&gt;
&lt;br /&gt;
Allerdings stimmt diese Rechnung natürlich nur, wenn wirklich ein 25MHz Quarz am Controller angeschlossen ist. Auf dem STM32F4-Discovery Board befindet sich aber nur ein 8MHz Quarz. Demnach gilt:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((8MHz / PLL_M(25)) * PLL_N(336)) / PLL_P(2) = 53.76MHz&lt;br /&gt;
&lt;br /&gt;
Der Controller läuft also nur mit 53.76MHz, wenn wie ober beschrieben ein Projekt erstellt wird. Allerdings kann dieses Problem durch ändern von den betroffen Defines behoben werden:&lt;br /&gt;
 &lt;br /&gt;
*Dazu geht man in die &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; Datei und passt zur Vollständigkeit erstmal die zum Controller passende Tabelle im &amp;quot;Kommentar-Header&amp;quot; an (Z.57f):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      HSE Frequency(Hz)                      | 8000000&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      PLL_M                                  | 8&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Danach passt man den PPL_M Define (Z.254) an:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/************************* PLL Parameters *************************************/&lt;br /&gt;
/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */&lt;br /&gt;
#define PLL_M      8&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Außerdem muss man den HSE_VALUE Define in der &#039;&#039;&#039;&#039;&#039;inc/stm32f4xx.h&#039;&#039;&#039;&#039;&#039; angepasst werden (Z.122):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#if !defined  (HSE_VALUE)&lt;br /&gt;
  #define HSE_VALUE    ((uint32_t)8000000) /*!&amp;lt; Value of the External oscillator in Hz */&lt;br /&gt;
&lt;br /&gt;
#endif /* HSE_VALUE */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine neue Berechnung zeigt:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((8MHz / PLL_M(8)) * PLL_N(336)) / PLL_P(2) = 168MHz&lt;br /&gt;
&lt;br /&gt;
Jetzt läuft der Controller mit maximaler Geschwindigkeit.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Achtung!:&lt;br /&gt;
In dem &amp;quot;Kommentar-Header&amp;quot; der &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; steht in der letzten Zeile immer:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      Require 48MHz for USB OTG FS,          | Disabled&lt;br /&gt;
*      SDIO and RNG clock                     |&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das ist jedoch falsch, weil der Takt für USB, SDIO und RNG immer mit der PLL über den Teiler PPL_Q eingestellt wird. Der Takt ist somit immer vorhanden und muss nicht extra Eingeschaltet werden. (Erspart langes Suchen, nach den entsprechenden Registern)&lt;br /&gt;
&lt;br /&gt;
===Die FPU===&lt;br /&gt;
====Allgemeines====&lt;br /&gt;
Damit die FPU richtig verwendet wird, müssen normalerweise zwei Bedingungen erfüllt sein:&lt;br /&gt;
&lt;br /&gt;
1. Der Controller muss in der Initialisierung-Funktion &#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; in &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; die FPU Hardware-seitig aktivieren&lt;br /&gt;
&lt;br /&gt;
2. Damit die FPU auch was zu tuen bekommt, müssen vom Compiler FPU-Instructions erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
Die Em::Blocks IDE verwendet standardmäßig die FPU, wenn eine Vorhanden ist. Hier wird die FPU Hardware-seitig aktiviert (&#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; Z.341):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* FPU settings ------------------------------------------------------------*/&lt;br /&gt;
  #if (__FPU_PRESENT == 1) &amp;amp;&amp;amp; (__FPU_USED == 1)&lt;br /&gt;
    SCB-&amp;gt;CPACR |= ((3UL &amp;lt;&amp;lt; 10*2)|(3UL &amp;lt;&amp;lt; 11*2));  /* set CP10 and CP11 Full Access */&lt;br /&gt;
  #endif&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
__FPU_PRESENT wird in der &#039;&#039;&#039;&#039;&#039;stm32f4xx.h&#039;&#039;&#039;&#039;&#039; definiert.&lt;br /&gt;
__FPU_USED wird von der IDE übernommen (siehe Build-Log): &#039;&#039;&#039;&#039;&#039;-D__FPU_USED&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Außerdem wird der Compiler von der IDE standardmäßig mit dem Argument &#039;&#039;&#039;&#039;&#039;-mfloat-abi=hard&#039;&#039;&#039;&#039;&#039; aufgerufen, wodurch FPU-Instructions erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
====FPU abschalten====&lt;br /&gt;
Um die FPU ab zu schalten (Mir würde jetzt nur Strom sparen als Grund einfallen) geht man wie folgt vor:&lt;br /&gt;
&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick Build options -&amp;gt; Device -&amp;gt; Policy&#039;&#039;&#039;&#039;&#039; wählt man &#039;&#039;&#039;&#039;&#039;Use target settings&#039;&#039;&#039;&#039;&#039; und über nimmt die Einstellungen, die vorher dort eingetragen waren, allerdings lässt man das Feld &#039;&#039;&#039;&#039;&#039;FP-hardware&#039;&#039;&#039;&#039;&#039; frei.&lt;br /&gt;
&lt;br /&gt;
[[Datei:fpu_1.png|FPU Abschalten Schritt 1]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;Compiler Settings -&amp;gt; Policy&#039;&#039;&#039;&#039;&#039; wählt man dann &#039;&#039;&#039;&#039;&#039;Use target options only&#039;&#039;&#039;&#039;&#039;. Dann kann man unter &#039;&#039;&#039;&#039;&#039;Categories&#039;&#039;&#039;&#039;&#039; die Option &#039;&#039;&#039;&#039;&#039;ARM FPU architecture&#039;&#039;&#039;&#039;&#039; auswählen. Dort stehen dann drei Möglichkeiten für die FPU zur Verfügung:&lt;br /&gt;
&lt;br /&gt;
1. Software-FPU-Library für Gleitkomma-Berechnung verwenden - Keine FPU-Instructions werden generiert (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=soft&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
2. Eine Mischung aus Software- und Hardware-FPU wird verwendet (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=softfp&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
3. Hardware-FPU wird für Gleitkomma-Berechnungen verwendet (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=hard&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
[[Datei:fpu_2.png|FPU Abschalten Schritt 2]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Um die FPU ab zu schalten wählt man natürlich die erste Möglichkeit.&lt;br /&gt;
Bei der 2. und 3. Möglichkeit fügt die IDE auch den Define &#039;&#039;&#039;&#039;&#039;__FPU_USED&#039;&#039;&#039;&#039;&#039; hinzu. Bei Der ersten Möglichkeit nicht. Der Code muss also nicht verändert / auskommentiert werden.&lt;br /&gt;
&lt;br /&gt;
Um die FPU wieder zu aktivieren müssen alle Schritte wieder rückgängig gemacht werden.&lt;br /&gt;
&lt;br /&gt;
Am besten ist es einfach mal alle Möglichkeiten im Einzelschritt durch zu probieren. Dann stellt man schnell fest, ob die FPU aktiviert wir oder nicht. Ein Blick in den erweiterten &#039;&#039;&#039;&#039;&#039;Build-Log&#039;&#039;&#039;&#039;&#039; gibt auch schnell Aufschluss darüber, wie der Compiler aufgerufen wird (siehe Kapitel [http://www.mikrocontroller.net/articles/STM32_-_Einstieg_mit_Em::Blocks#Compilieren Compilieren]).&lt;br /&gt;
&lt;br /&gt;
====Test Programm für die FPU====&lt;br /&gt;
Hier ein kleines Testprogramm, dass misst wie viele Taktzyklen für eine Gleitkomma-Multiplikation gebraucht werden. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define CORE_SysTickEn()    (*((u32*)0xE0001000)) = 0x40000001&lt;br /&gt;
#define CORE_SysTickDis()   (*((u32*)0xE0001000)) = 0x40000000&lt;br /&gt;
#define CORE_GetSysTick()   (*((u32*)0xE0001004))&lt;br /&gt;
&lt;br /&gt;
uint32_t t1, t2, dt;&lt;br /&gt;
float x, y, z;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    x = 53.64f;&lt;br /&gt;
    y = 0.27f;&lt;br /&gt;
&lt;br /&gt;
    CORE_SysTickEn();&lt;br /&gt;
    t1 = CORE_GetSysTick();&lt;br /&gt;
&lt;br /&gt;
    z = x * y;&lt;br /&gt;
&lt;br /&gt;
    t2 = CORE_GetSysTick();&lt;br /&gt;
    CORE_SysTickDis();&lt;br /&gt;
&lt;br /&gt;
    dt = t2 - t1;&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mein Ergebnis:&lt;br /&gt;
*Mit Hardware-FPU:  dt = 25&lt;br /&gt;
*Ohne Hardware-FPU: dt = 83&lt;br /&gt;
&lt;br /&gt;
==Einbinden der Standard Peripheral Library==&lt;br /&gt;
Um nicht immer die einzelnen Register, wie im ersten &amp;quot;bare-metal&amp;quot; Beispiel, aus dem Reference-Manual zu suchen und zu beschreiben, gibt es von ST die Standard Peripheral Library, die diese Aufgaben übernimmt und mit der sich die &amp;quot;normale/grundlegende&amp;quot; (Alles außer USB und Ethernet) Peripherie recht einfach steuern lässt. Um die Library zu verwenden erzeugt man wie oben beschrieben ein neues Grundgerüst und kopiert als erstes den Ordner &#039;&#039;&#039;&#039;&#039;Libraries\STM32F4xx_StdPeriph_Driver&#039;&#039;&#039;&#039;&#039; aus dem Standard-Peripheral-Library Download in das Projekt-Verzeichnis. Außerdem muss man die Datei &#039;&#039;&#039;&#039;&#039;Project\STM32F4xx_StdPeriph_Templates\stm32f4xx_conf.h&#039;&#039;&#039;&#039;&#039; ebenfalls aus dem Standard-Peripheral-Library Download in den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projektes kopieren. In der IDE fügt man den Include-Path &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\inc&#039;&#039;&#039;&#039;&#039; hinzufügen, wie bei der CMSIS-Library (s.o.).&lt;br /&gt;
Außerdem muss noch &#039;&#039;&#039;&#039;&#039;USE_STDPERIPH_DRIVER&#039;&#039;&#039;&#039;&#039; als Define in der IDE hinzugefügt werden (s.o.).&lt;br /&gt;
Danach fügt man die Source- und Include-Dateien aus dem Ordner &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\inc&#039;&#039;&#039;&#039;&#039; und &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\src&#039;&#039;&#039;&#039;&#039; dem Project mit &#039;&#039;&#039;&#039;&#039;&amp;lt;Project Name&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Add files&#039;&#039;&#039;&#039;&#039; hinzu, allerdings nur die, für welche auch der Controller die entsprechende Peripherie besitzt. Beim STM32F4-Discovery Board / STM32F407VG Controller dürfen also nicht folgende Dateien nicht mit hinzugefügt werden, weil diese Peripherie nur bei anderen Controller vorhanden ist:&lt;br /&gt;
&lt;br /&gt;
*stm32f4xx_dma2d.c/.h&lt;br /&gt;
*stm32f4xx_fmc.c/.h&lt;br /&gt;
*stm32f4xx_ltdc.c/.h&lt;br /&gt;
*stm32f4xx_sai.c/.h&lt;br /&gt;
&lt;br /&gt;
Daraus resultiert folgende Struktur:&lt;br /&gt;
&lt;br /&gt;
[[Datei:stdperiphlib_2.png|Header-Struktur]] [[Datei:stdperiphlib_1.png|Source-Struktur]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Anschließen kann die Standard-Peripheral-Library benutz werden.&lt;br /&gt;
main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);&lt;br /&gt;
&lt;br /&gt;
    GPIO_InitTypeDef GPIOD_InitStructure;&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Mode = GPIO_Mode_OUT;&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Pin = GPIO_Pin_15;&lt;br /&gt;
    GPIO_Init(GPIOD, &amp;amp;GPIOD_InitStructure);&lt;br /&gt;
&lt;br /&gt;
    GPIO_SetBits(GPIOD, GPIO_Pin_15);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Booten aus dem SRAM==&lt;br /&gt;
STM32 Controller haben die Möglichkeit Code aus dem Flash als auch aus dem SRAM auszuführen. Um eine Anwenung per Debugger in des SRAM zu laden sind nur wenige Schritte erforderlich:&lt;br /&gt;
&lt;br /&gt;
*Um das Linkerscript für den SRAM zu verwenden geht man zu: &#039;&#039;&#039;&#039;&#039;Build options... -&amp;gt; Device&#039;&#039;&#039;&#039;&#039; dort wählt man unter &#039;&#039;&#039;&#039;&#039;Policy&#039;&#039;&#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;Use target settings&#039;&#039;&#039;&#039;&#039; aus und übernimmt die vorherigen Einstellungen, nur unter &#039;&#039;&#039;&#039;&#039;Linker script*&#039;&#039;&#039;&#039;&#039; gibt man &#039;&#039;&#039;&#039;&#039;.\stm32f407vg_sram.ld&#039;&#039;&#039;&#039;&#039; an&lt;br /&gt;
&lt;br /&gt;
*Dann muss man noch unter &#039;&#039;&#039;&#039;&#039;Debug -&amp;gt; Interfaces -&amp;gt; Settings&#039;&#039;&#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;Vector table start&#039;&#039;&#039;&#039;&#039; auf 0x20000000 ändern und &#039;&#039;&#039;&#039;&#039;Execute from RAM&#039;&#039;&#039;&#039;&#039; auswählen.&lt;br /&gt;
&lt;br /&gt;
Anschließend kann man die Anwendung ganz normal debuggen. Nach einem Reset muss die Anwenung erneut mit dem Debugger gestartet werden.&lt;br /&gt;
&lt;br /&gt;
=Fortsetzung folgt..=&lt;br /&gt;
Kritik, Wünsche usw. sind gerne erwünscht, am besten hier in den Thread posten: [http://www.mikrocontroller.net/topic/323750 Neues STM32 Tutorial]&lt;br /&gt;
&lt;br /&gt;
[[Category:ARM]]&lt;br /&gt;
[[Category:STM32]]&lt;/div&gt;</summary>
		<author><name>Avrprogger</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=STM32_-_Einstieg_mit_Em::Blocks&amp;diff=81493</id>
		<title>STM32 - Einstieg mit Em::Blocks</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=STM32_-_Einstieg_mit_Em::Blocks&amp;diff=81493"/>
		<updated>2014-02-09T18:39:21Z</updated>

		<summary type="html">&lt;p&gt;Avrprogger: fgh&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In diesem Tutorial werde ich versuchen, möglichst einfach, die ersten Schritte zur Entwicklung von STM32 Anwenungen mit der Em::Blocks IDE zu erklären. Hier soll nicht so stark auf die einzelnen Peripherie-Module der Controller eingegangen werden, sondern mehr auf die IDE und die verschieden Libraries, wie die CMSIS Library, die DSP-Library, die Standard-Peripheral-Library, die USB-Library und vllt. über Ethernet. Ich denke ein Kapitel zu FreeRTOS wird es auch geben. Auserdem steht im Vordergrund Sachen wie z.B. booten aus dem SRAM, In-Application-Programming, FPU, Core-Coupled-RAM usw. Mal sehn wie weit ich komme ;)&lt;br /&gt;
&lt;br /&gt;
==Die Entwicklungsumgebung==&lt;br /&gt;
===Hardware===&lt;br /&gt;
Zum testen der Anwendungen, benutze ich das STM32F4-Discovery Board, welches einen Debugger, Peripherie und natürlich einen STM32 Controller (STM32F407VGT6) enthält. Deshalb sind alle Beispiele hier für den STM32F407VG Controller ausgelegt, können aber meisten 1:1 auf andere Controller portiert werden. Ich werde auch möglichsts keine STM32F4-Discovery Board spezifischen Libraries verwenden, damit der Portierungs-Vorgang möglichsts einfach bleibt.&lt;br /&gt;
&lt;br /&gt;
===Software===&lt;br /&gt;
In diesem Tutorial verwende ich [http://www.emblocks.org/ Em::Blocks] als IDE. Em::Blocks ist eine kostenlose, uneingeschränkte IDE, die alle STM32 Mikrcontroller unterstützt und sehr einfach zu bedienen ist.&lt;br /&gt;
nach dem Download kann die IDE per Dialog, sehr einfach, installiert werden. Als Compiler beinhaltet Em::Blocks den &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
Die IDE unterstützt zurzeit den ST-Link, den J-Link und es gibt eine Generic-Vorlage, durch welche andere Debugger konfiguriert werden können.&lt;br /&gt;
&lt;br /&gt;
Außerdem muss noch der passende Treiber für den Debugger installiert werden. Verwendet man ein Discovery-Board muss der [http://www.st.com/web/catalog/tools/FM146/CL1984/SC724/SS1677/PF251168 ST-Link/V2]-Treiber heruntergeladen und installiert werden. (Die Installation muss evtl. als Administrator ausgeführt werden, da sonst die Installation unvollständig wird.) Nach der Installation des Treibers kann man den Debugger über die entsprechende USB Schnittstelle an den PC anschließen und es sollte die Meldung von Windows kommen, dass der richtige Treiber gefunden wurde.&lt;br /&gt;
&lt;br /&gt;
===Libraries===&lt;br /&gt;
Zum programmieren benötigt man noch die [http://www.arm.com/products/processors/cortex-m/cortex-microcontroller-software-interface-standard.php CMSIS] und die Standard-Peripheral-Library (z.B. für die F4 Controller [http://www.st.com/stonline/stappl/productcatalog/app?page=partNumberSearchPage&amp;amp;levelid=SS1577&amp;amp;parentid=1743&amp;amp;resourcetype=SW Standard-Peripheral-Library-F4]), die man am besten in einen Ordner (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\STM32&#039;&#039;&#039;&#039;&#039;) entpackt&lt;br /&gt;
&lt;br /&gt;
==Basis-Wissen zur IDE==&lt;br /&gt;
Einige Grundfunktionalitäten der IDE:&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von Dateien zum Projekt===&lt;br /&gt;
Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf &amp;lt;ProjektName&amp;gt; -&amp;gt; Add files...&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Enfernen von Dateien aus dem Projekt===&lt;br /&gt;
Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf die Datei / mehrere Dateien auswählen -&amp;gt; Remove file from project&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
Die Dateien werden lediglich aus dem Projekt entfernt und nicht von der Festplatte gelöscht.&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von Include-Pfaden===&lt;br /&gt;
Sofern die Include-Datei(en) nicht im standard Include-Ordner &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; des Projektes liegen, muss man den Pfad zum Projekt hinzufügen, damit der Compiler die Include-Dateien später auch finden kann. Man geht wie folgt vor: Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf &amp;lt;ProjektName&amp;gt; -&amp;gt; Build options... -&amp;gt; Search Directories -&amp;gt; Add&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Compilieren===&lt;br /&gt;
Entweder über das &#039;&#039;&#039;&#039;&#039;Build&#039;&#039;&#039;&#039;&#039; Menü oder über &#039;&#039;&#039;&#039;&#039;F7&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Um eine genau Ausgabe des Compiler-Aufrufes mit allen Argumenten zu bekommen, geht man im &#039;&#039;&#039;&#039;&#039;Settings&#039;&#039;&#039;&#039;&#039; Menü auf &#039;&#039;&#039;&#039;&#039;Tools...&#039;&#039;&#039;&#039;&#039; und dann auf &#039;&#039;&#039;&#039;&#039;Toolchain executables&#039;&#039;&#039;&#039;&#039;. Ganz unten, unter &#039;&#039;&#039;&#039;&#039;Logging&#039;&#039;&#039;&#039;&#039; kann man dann &#039;&#039;&#039;&#039;&#039;Full command line&#039;&#039;&#039;&#039;&#039; auswählen.&lt;br /&gt;
&lt;br /&gt;
===Debuggen===&lt;br /&gt;
*Als erstes den Debugger starten über das &#039;&#039;&#039;&#039;&#039;Debug&#039;&#039;&#039;&#039;&#039; Menü und &#039;&#039;&#039;&#039;&#039;Start/stop Debug Session&#039;&#039;&#039;&#039;&#039; oder über &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
*Danach läuft die Anwendung auf dem Controller und warten im &#039;&#039;&#039;&#039;&#039;Reset_Handler&#039;&#039;&#039;&#039;&#039; auf Einzelschritt- bzw. Run- Befehle (&#039;&#039;&#039;&#039;&#039;F5, F10, F11&#039;&#039;&#039;&#039;&#039; usw..(siehe &#039;&#039;&#039;&#039;&#039;Debug-Menü&#039;&#039;&#039;&#039;&#039; für alle Möglichkeiten))&lt;br /&gt;
&lt;br /&gt;
*Mit &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039; wird die Debug-Session auch wieder beendet&lt;br /&gt;
&lt;br /&gt;
*Unter &#039;&#039;&#039;&#039;&#039;Debug -&amp;gt; Interfaces -&amp;gt; Target settings&#039;&#039;&#039;&#039;&#039; können Eigenschaften, wie z.B &#039;&#039;&#039;&#039;&#039;Run to main()&#039;&#039;&#039;&#039;&#039; aktiviert werden.&lt;br /&gt;
&lt;br /&gt;
===Projekt als Template abspeichern===&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;File -&amp;gt; Save project as template...&#039;&#039;&#039;&#039;&#039;. Das Template erscheint dann im Projekt-Dialog unter &#039;&#039;&#039;&#039;&#039;User templates&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Das erste Projekt erstellen==&lt;br /&gt;
Hier erkläre ich, wie man am Besten (aus meiner Sicht), ein neues Projekt von Grund auf erstellt, sodass man hinterher, den Controller-Kern über die CMSIS-Library und die Peripherie über die Register steuern kann.&lt;br /&gt;
&lt;br /&gt;
===1. Projekt mit der IDE erstellen===&lt;br /&gt;
Nach der Installation der oben beschriebenen Komponenten erstellt man am besten ein Verzeichnis (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\EmBlocks&#039;&#039;&#039;&#039;&#039;), indem später alle Projekte gespeichert werden. Für Libraries kann man auch noch ein Verzeichnis (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\STM32&#039;&#039;&#039;&#039;&#039;) erstellen, wo alle Libraries gespeichert werden, die man für die Projekt brauchen.&lt;br /&gt;
&lt;br /&gt;
Als nächstes starten man EmBlocks. Bei dem ersten Start öffnet sich ein Fenster, wo verschiedene Compiler angezeigt werden, die Em::Blocks findet. Dort wählt man den &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039; aus und klickt &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039;. Nun sollte sich das Hauptfenster von Em::Blocks öffnen. Über &#039;&#039;&#039;&#039;&#039;Create a new Project&#039;&#039;&#039;&#039;&#039; oder &#039;&#039;&#039;&#039;&#039;File -&amp;gt; New -&amp;gt; Project&#039;&#039;&#039;&#039;&#039; ruft man den Projekt-Dialog auf und kann ein neues Projekt erzeugen.&lt;br /&gt;
&lt;br /&gt;
Auf der Ersten Seite wählen man den &#039;&#039;&#039;&#039;&#039;STmicro-ARM&#039;&#039;&#039;&#039;&#039; Projekt-Typ aus.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_1.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auf der nächsten Seite wird man darauf hingewiesen, dass das der entsprechende Projekt-Typ-Dialog ausgeführt wird. Hier kann man ein Häkchen bei &#039;&#039;&#039;&#039;&#039;Skip this page next time&#039;&#039;&#039;&#039;&#039; setzen und auf &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; klicken.&lt;br /&gt;
&lt;br /&gt;
Im nächsten Schritt wählen man das zuvor erstellt Verzeichnis unter &#039;&#039;&#039;&#039;&#039;Folder to create Project in&#039;&#039;&#039;&#039;&#039; aus, indem später alle Projekt gespeichert werden. Außerdem geben wir dem Projekt einen Namen (z.B. &#039;&#039;&#039;&#039;&#039;FirstProject&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_2.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danach muss man einen Compiler auswählen und bestimmen, welche Projekt-Konfigurationen erszeugt werden sollen. Unter &#039;&#039;&#039;&#039;&#039;Compiler&#039;&#039;&#039;&#039;&#039; wählt man &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039; und man kann das Häkchen bei &#039;&#039;&#039;&#039;&#039;Create &amp;quot;Release&amp;quot; configuration&#039;&#039;&#039;&#039;&#039; entfernen, da diese unnötig ist, die Debug-Konfiguration sollte eig. immer ausreichen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_3.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auf den folgenden Seite wird der Controller ausgewählt. Verwendet man ein STM32F4-Discovery Board müssen folgende Dinge gewählt werden: &#039;&#039;&#039;&#039;&#039;Cortex_M4 (F3xx - F4xx) -&amp;gt; STM32F4xx (Cortex M4 with FPU) -&amp;gt; STM32F407VG&#039;&#039;&#039;&#039;&#039;. Leider sind die Auswahl Möglichkeiten nicht ganz richtig, da auch die F3 Controller einen Cortex M4 Kern und eine FPU haben (Ist aber nicht so wichtig, ist nur eine formale Sache). Außerdem entfernt man das Häkchen bei &#039;&#039;&#039;&#039;&#039;Standard Peripherals Library&#039;&#039;&#039;&#039;&#039; (Wie man die Standard-Peripheral-Library einbindet und verwendet erkläre ich später). Man kann auch das Häkchen bei &#039;&#039;&#039;&#039;&#039;Create hex file for Realease target&#039;&#039;&#039;&#039;&#039; entfernen.&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;Stack Size&#039;&#039;&#039;&#039;&#039; und &#039;&#039;&#039;&#039;&#039;Heap Size&#039;&#039;&#039;&#039;&#039; wird die Größe von Stack und Heap festgelegt. Für eine erste Anwendung kann man die Einstellungen so lassen (Stack-Size: 0x0100 =&amp;gt; 256 Byte Stack und Heap-Size: 0x0000 =&amp;gt; kein Heap). Mit &#039;&#039;&#039;&#039;&#039;Finish&#039;&#039;&#039;&#039;&#039; ist der Projekt Dialog abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_4.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danach sollten sich zwei neue Fenster öffnen, um die Debug-Eigenschaften fest zu legen.&lt;br /&gt;
Verwendet man ein Discovery Board/ST-Link müssen die Einstellungen wie auf dem Bild gewählt werden. Über den Button &#039;&#039;&#039;&#039;&#039;Settings&#039;&#039;&#039;&#039;&#039; öffnet sich das zweite Fenster, falls sich dieses nicht schon von alleine öffnen sollte. Nach den Schließen der Fenster über &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; ist der Projekt Dialog beendet und ein neues Projekt steht zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_5_1.png|Debug Eigenschaften 1. Fenster]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_5_2.png|Debug Eigenschaften 2. Fenster]]&lt;br /&gt;
&lt;br /&gt;
===2. CMSIS-Library und Startup-Code hinzufügen===&lt;br /&gt;
Wenn man sich, nachdem man ein neues Projekt in der IDE erstellt hat, die bereits vorhandenen Dateien im Projekt ansieht, stellt man fest, das bereits ein Ordner &#039;&#039;&#039;&#039;&#039;cmsis&#039;&#039;&#039;&#039;&#039; existiert, der einige wichtige Include-Dateien der CMSIS-Library enthält. Allerdings sind das wirklich nur die wichtigsten Include-Dateien der CMSIS-Library und dazu noch, die aus einer älternen Version. Ich ziehe es deshalb vor die &amp;quot;Mini-CMSIS-Libraray&amp;quot; und die &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c/.h&#039;&#039;&#039;&#039;&#039; Dateien des Projektes durch aktuellere Versionen zu ersetzen. So ist später auch die Integration  von anderen Libraries, wie z.B. der CMSIS-DSP-Libarary einfacher.  &lt;br /&gt;
&lt;br /&gt;
Zunächst gehen man in das Projekt-Verzeichnis und löscht:&lt;br /&gt;
*Den Ordner &#039;&#039;&#039;&#039;&#039;cmsis&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Alle Dateien im Include Verzeichnis &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; im &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner&lt;br /&gt;
&lt;br /&gt;
Außerdem entfernt man auch alle gelöschten Dateien in der IDE aus dem Projekt mit &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Rechts Klick -&amp;gt; Remove file from project&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Es sollte folgende Verzeichnis Struktur überbleiben:&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_6.png|Überbleibende Dateien]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Jetzt müssen die gelöschten Dateien durch die aktuelleren ersetzt werden.&lt;br /&gt;
&lt;br /&gt;
*Dazu kopieren man den gesamten Ordner &#039;&#039;&#039;&#039;&#039;CMSIS&#039;&#039;&#039;&#039;&#039; aus dem CMSIS Download in das Projekt Verzeichnis.&lt;br /&gt;
&lt;br /&gt;
*Aus dem Standard-Peripheral-Library Download kopiert man von &#039;&#039;&#039;&#039;&#039;Libraries\CMSIS\Device\ST\STM32F4xx\Include&#039;&#039;&#039;&#039;&#039; alle Dateien in den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projekt Verzeichnisses&lt;br /&gt;
&lt;br /&gt;
*Aus der Standard-Peripheral-Library kopieren man ebenfalls von &#039;&#039;&#039;&#039;&#039;Libraries\CMSIS\Device\ST\STM32F4xx\Source\Templates&#039;&#039;&#039;&#039;&#039; die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; in den &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner des Projekts&lt;br /&gt;
&lt;br /&gt;
Anschließend müssen die neuen Dateien in der IDE dem Projekt hinzugefügt werden. Dazu benutzt man &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Rechts Klick -&amp;gt; Add files&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
*Aus dem &#039;&#039;&#039;&#039;&#039;CMSIS&#039;&#039;&#039;&#039;&#039; Ordner im Projekt Verzeichnis werden aus den Unterorder &#039;&#039;&#039;&#039;&#039;Include&#039;&#039;&#039;&#039;&#039; folgende Dateien dem Projekt hinzugefügt:&lt;br /&gt;
**arm_common_tables.h&lt;br /&gt;
**arm_const_structs.h&lt;br /&gt;
**arm_math.h&lt;br /&gt;
**core_cm4.h&lt;br /&gt;
**core_cm4_simd.h&lt;br /&gt;
**core_cmFunc.h&lt;br /&gt;
**core_cmInstr.h&lt;br /&gt;
*Alle Dateien aus den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projektes&lt;br /&gt;
*Die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; aus dem &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner&lt;br /&gt;
&lt;br /&gt;
So sollte die Struktur dann aussehen:&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_7.png|Anwenungs-Grundgerüst]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Da einige Dateien der Libraries später bearbeitet werden müssen und Schreibgeschützt sind, weise ich hier schonmal darauf hin, das der Schreibschutz in der IDE über &#039;&#039;&#039;&#039;&#039;Rechts Klick auf die Datei -&amp;gt; Properties -&amp;gt; Häkchen bei &amp;quot;File is read only&amp;quot; entfernen&#039;&#039;&#039;&#039;&#039; entfert werden kann.&lt;br /&gt;
&lt;br /&gt;
Damit die IDE die Header-Dateien der CMSIS Library auch finden kann, weil diese ja nicht im standard Include Ordner &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; liegen, muss unter &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Build Options -&amp;gt; Search Directories&#039;&#039;&#039;&#039;&#039; der Pfad &#039;&#039;&#039;&#039;&#039;CMSIS\Include&#039;&#039;&#039;&#039;&#039; hinzugefügt werden.&lt;br /&gt;
&lt;br /&gt;
Compiliert man jetzt das Projekt mit &#039;&#039;&#039;&#039;&#039;F7&#039;&#039;&#039;&#039;&#039; gibt es ein paar Fehler Meldungen, weil keine Controller-Reihe ausgewählt wurde. Ebenfalls unter &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Build Options -&amp;gt; Compiler Settings -&amp;gt; #defines&#039;&#039;&#039;&#039;&#039; wird der Define &#039;&#039;&#039;&#039;&#039;STM32F40_41xxx&#039;&#039;&#039;&#039;&#039; hinzugefügt.&lt;br /&gt;
&lt;br /&gt;
Beim erneuten Compilieren sollten sich nun keine neuen Fehler ergeben.&lt;br /&gt;
&lt;br /&gt;
===Das erste Programm===&lt;br /&gt;
Nachdem ein grundsätzliches &amp;quot;Gerüst&amp;quot; fertig ist, kann man den ersten Code schreiben.&lt;br /&gt;
main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC-&amp;gt;AHB1ENR |= RCC_AHB1ENR_GPIODEN;    //Takt für GPIO aktivieren&lt;br /&gt;
    GPIOD-&amp;gt;MODER |= GPIO_MODER_MODER15_0;   //GPIOD Pin15 als Ausgang&lt;br /&gt;
    GPIOD-&amp;gt;BSRRL |= GPIO_BSRR_BS_15;        //GPIOD Pin15 auf High ziehen&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Download: [[Datei:FirstProject.zip]]&lt;br /&gt;
&lt;br /&gt;
Mit &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039; wird dann der Debugger gestartet. Hat der Debugger das Projekt erfolgreich übertragen kann die Ausführung mit &#039;&#039;&#039;&#039;&#039;F5&#039;&#039;&#039;&#039;&#039; begonnen werden.&lt;br /&gt;
&lt;br /&gt;
==Takt, FPU usw.==&lt;br /&gt;
===Der Takt===&lt;br /&gt;
Jeder Controller oder Prozessor braucht einen Takt, indem er die einzelnen Maschinen-Befehle abarbeiten kann.&lt;br /&gt;
Bei den STM32 Mikrocontrollern kann dieser Takt aus verschiedenen Quellen kommen:&lt;br /&gt;
&lt;br /&gt;
1. High Speed Internal Oszillator (HSI)&lt;br /&gt;
&lt;br /&gt;
2. High Speed External Oszillator (HSE)&lt;br /&gt;
&lt;br /&gt;
3. Low Speed Internal Oszillator (LSI)&lt;br /&gt;
&lt;br /&gt;
4. Low Speed External Oszillator (LSE)&lt;br /&gt;
&lt;br /&gt;
5. Phase-Locked Loop (PLL) (generiert den Takt aus den ersten vier Taktquellen durch Teiler und Faktoren)&lt;br /&gt;
&lt;br /&gt;
Nach einem Reset wird der Controller aus der HSI Taktquelle versorgt (16MHz beim STM32F407VG). Um die voll Performance des Controllers zu erreichen muss die PLL verwendet werden, welche den Takt durch geschickte Teiler und Faktoren vervielfältigt, sodass am Ende der Controller mit der maximalen Taktfrequenz läuft. Die notwendige Initialisierung der PLL findet in der Funktion &#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; statt. Die PLL erzeugt zunächst einen Basistakt:&lt;br /&gt;
&lt;br /&gt;
PLL_VCO = (F_HSE / PLL_M) * PLL_N&lt;br /&gt;
&lt;br /&gt;
Aus diesem Takt wird dann der Takt für den Controller-Kern abgeleitet:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = PLL_VCO / PLL_P&lt;br /&gt;
&lt;br /&gt;
Und der Takt für SDIO / USB / RNG (48MHz):&lt;br /&gt;
&lt;br /&gt;
48MHz = PLL_VCO / PLL_Q&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Durch weiter Teiler werden, die Takte für die einzelnen Busse erzeugt, da diese nicht alle beliebig schnell betrieben werden dürfen.&lt;br /&gt;
&lt;br /&gt;
Genaue Angaben findet man zu dem jeweiligen Clock-System des Controllers im Reference Manual.&lt;br /&gt;
&lt;br /&gt;
Ein Blick in den &amp;quot;Kommentar-Header&amp;quot; verrät, dass von einem externen (HSE) Oszillator von 25MHz ausgegangen wird, der die PLL versorgen soll.&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((25MHz / PLL_M(25)) * PLL_N(336)) / PLL_P(2) = 168MHz&lt;br /&gt;
&lt;br /&gt;
Allerdings stimmt diese Rechnung natürlich nur, wenn wirklich ein 25MHz Quarz am Controller angeschlossen ist. Auf dem STM32F4-Discovery Board befindet sich aber nur ein 8MHz Quarz. Demnach gilt:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((8MHz / PLL_M(25)) * PLL_N(336)) / PLL_P(2) = 53.76MHz&lt;br /&gt;
&lt;br /&gt;
Der Controller läuft also nur mit 53.76MHz, wenn wie ober beschrieben ein Projekt erstellt wird. Allerdings kann dieses Problem durch ändern von den betroffen Defines behoben werden:&lt;br /&gt;
 &lt;br /&gt;
*Dazu geht man in die &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; Datei und passt zur Vollständigkeit erstmal die zum Controller passende Tabelle im &amp;quot;Kommentar-Header&amp;quot; an (Z.57f):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      HSE Frequency(Hz)                      | 8000000&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      PLL_M                                  | 8&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Danach passt man den PPL_M Define (Z.254) an:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/************************* PLL Parameters *************************************/&lt;br /&gt;
/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */&lt;br /&gt;
#define PLL_M      8&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Außerdem muss man den HSE_VALUE Define in der &#039;&#039;&#039;&#039;&#039;inc/stm32f4xx.h&#039;&#039;&#039;&#039;&#039; angepasst werden (Z.122):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#if !defined  (HSE_VALUE)&lt;br /&gt;
  #define HSE_VALUE    ((uint32_t)8000000) /*!&amp;lt; Value of the External oscillator in Hz */&lt;br /&gt;
&lt;br /&gt;
#endif /* HSE_VALUE */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine neue Berechnung zeigt:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((8MHz / PLL_M(8)) * PLL_N(336)) / PLL_P(2) = 168MHz&lt;br /&gt;
&lt;br /&gt;
Jetzt läuft der Controller mit maximaler Geschwindigkeit.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Achtung!:&lt;br /&gt;
In dem &amp;quot;Kommentar-Header&amp;quot; der &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; steht in der letzten Zeile immer:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      Require 48MHz for USB OTG FS,          | Disabled&lt;br /&gt;
*      SDIO and RNG clock                     |&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das ist jedoch falsch, weil der Takt für USB, SDIO und RNG immer mit der PLL über den Teiler PPL_Q eingestellt wird. Der Takt ist somit immer vorhanden und muss nicht extra Eingeschaltet werden. (Erspart langes Suchen, nach den entsprechenden Registern)&lt;br /&gt;
&lt;br /&gt;
===Die FPU===&lt;br /&gt;
====Allgemeines====&lt;br /&gt;
Damit die FPU richtig verwendet wird, müssen normalerweise zwei Bedingungen erfüllt sein:&lt;br /&gt;
&lt;br /&gt;
1. Der Controller muss in der Initialisierung-Funktion &#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; in &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; die FPU Hardware-seitig aktivieren&lt;br /&gt;
&lt;br /&gt;
2. Damit die FPU auch was zu tuen bekommt, müssen vom Compiler FPU-Instructions erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
Die Em::Blocks IDE verwendet standardmäßig die FPU, wenn eine Vorhanden ist. Hier wird die FPU Hardware-seitig aktiviert (&#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; Z.341):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* FPU settings ------------------------------------------------------------*/&lt;br /&gt;
  #if (__FPU_PRESENT == 1) &amp;amp;&amp;amp; (__FPU_USED == 1)&lt;br /&gt;
    SCB-&amp;gt;CPACR |= ((3UL &amp;lt;&amp;lt; 10*2)|(3UL &amp;lt;&amp;lt; 11*2));  /* set CP10 and CP11 Full Access */&lt;br /&gt;
  #endif&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
__FPU_PRESENT wird in der &#039;&#039;&#039;&#039;&#039;stm32f4xx.h&#039;&#039;&#039;&#039;&#039; definiert.&lt;br /&gt;
__FPU_USED wird von der IDE übernommen (siehe Build-Log): &#039;&#039;&#039;&#039;&#039;-D__FPU_USED&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Außerdem wird der Compiler von der IDE standardmäßig mit dem Argument &#039;&#039;&#039;&#039;&#039;-mfloat-abi=hard&#039;&#039;&#039;&#039;&#039; aufgerufen, wodurch FPU-Instructions erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
====FPU abschalten====&lt;br /&gt;
Um die FPU ab zu schalten (Mir würde jetzt nur Strom sparen als Grund einfallen) geht man wie folgt vor:&lt;br /&gt;
&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick Build options -&amp;gt; Device -&amp;gt; Policy&#039;&#039;&#039;&#039;&#039; wählt man &#039;&#039;&#039;&#039;&#039;Use target settings&#039;&#039;&#039;&#039;&#039; und über nimmt die Einstellungen, die vorher dort eingetragen waren, allerdings lässt man das Feld &#039;&#039;&#039;&#039;&#039;FP-hardware&#039;&#039;&#039;&#039;&#039; frei.&lt;br /&gt;
&lt;br /&gt;
[[Datei:fpu_1.png|FPU Abschalten Schritt 1]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;Compiler Settings -&amp;gt; Policy&#039;&#039;&#039;&#039;&#039; wählt man dann &#039;&#039;&#039;&#039;&#039;Use target options only&#039;&#039;&#039;&#039;&#039;. Dann kann man unter &#039;&#039;&#039;&#039;&#039;Categories&#039;&#039;&#039;&#039;&#039; die Option &#039;&#039;&#039;&#039;&#039;ARM FPU architecture&#039;&#039;&#039;&#039;&#039; auswählen. Dort stehen dann drei Möglichkeiten für die FPU zur Verfügung:&lt;br /&gt;
&lt;br /&gt;
1. Software-FPU-Library für Gleitkomma-Berechnung verwenden - Keine FPU-Instructions werden generiert (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=soft&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
2. Eine Mischung aus Software- und Hardware-FPU wird verwendet (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=softfp&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
3. Hardware-FPU wird für Gleitkomma-Berechnungen verwendet (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=hard&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
[[Datei:fpu_2.png|FPU Abschalten Schritt 2]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Um die FPU ab zu schalten wählt man natürlich die erste Möglichkeit.&lt;br /&gt;
Bei der 2. und 3. Möglichkeit fügt die IDE auch den Define &#039;&#039;&#039;&#039;&#039;__FPU_USED&#039;&#039;&#039;&#039;&#039; hinzu. Bei Der ersten Möglichkeit nicht. Der Code muss also nicht verändert / auskommentiert werden.&lt;br /&gt;
&lt;br /&gt;
Um die FPU wieder zu aktivieren müssen alle Schritte wieder rückgängig gemacht werden.&lt;br /&gt;
&lt;br /&gt;
Am besten ist es einfach mal alle Möglichkeiten im Einzelschritt durch zu probieren. Dann stellt man schnell fest, ob die FPU aktiviert wir oder nicht. Ein Blick in den erweiterten &#039;&#039;&#039;&#039;&#039;Build-Log&#039;&#039;&#039;&#039;&#039; gibt auch schnell Aufschluss darüber, wie der Compiler aufgerufen wird (siehe Kapitel [http://www.mikrocontroller.net/articles/STM32_-_Einstieg_mit_Em::Blocks#Compilieren Compilieren]).&lt;br /&gt;
&lt;br /&gt;
====Test Programm für die FPU====&lt;br /&gt;
Hier ein kleines Testprogramm, dass misst wie viele Taktzyklen für eine Gleitkomma-Multiplikation gebraucht werden. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define CORE_SysTickEn()    (*((u32*)0xE0001000)) = 0x40000001&lt;br /&gt;
#define CORE_SysTickDis()   (*((u32*)0xE0001000)) = 0x40000000&lt;br /&gt;
#define CORE_GetSysTick()   (*((u32*)0xE0001004))&lt;br /&gt;
&lt;br /&gt;
uint32_t t1, t2, dt;&lt;br /&gt;
float x, y, z;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    x = 53.64f;&lt;br /&gt;
    y = 0.27f;&lt;br /&gt;
&lt;br /&gt;
    CORE_SysTickEn();&lt;br /&gt;
    t1 = CORE_GetSysTick();&lt;br /&gt;
&lt;br /&gt;
    z = x * y;&lt;br /&gt;
&lt;br /&gt;
    t2 = CORE_GetSysTick();&lt;br /&gt;
    CORE_SysTickDis();&lt;br /&gt;
&lt;br /&gt;
    dt = t2 - t1;&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mein Ergebnis:&lt;br /&gt;
*Mit Hardware-FPU:  dt = 25&lt;br /&gt;
*Ohne Hardware-FPU: dt = 83&lt;br /&gt;
&lt;br /&gt;
Download: [[Datei:FPU_Test.zip]]&lt;br /&gt;
&lt;br /&gt;
==Einbinden der Standard Peripheral Library==&lt;br /&gt;
Um nicht immer die einzelnen Register, wie im ersten &amp;quot;bare-metal&amp;quot; Beispiel, aus dem Reference-Manual zu suchen und zu beschreiben, gibt es von ST die Standard Peripheral Library, die diese Aufgaben übernimmt und mit der sich die &amp;quot;normale/grundlegende&amp;quot; (Alles außer USB und Ethernet) Peripherie recht einfach steuern lässt. Um die Library zu verwenden erzeugt man wie oben beschrieben ein neues Grundgerüst und kopiert als erstes den Ordner &#039;&#039;&#039;&#039;&#039;Libraries\STM32F4xx_StdPeriph_Driver&#039;&#039;&#039;&#039;&#039; aus dem Standard-Peripheral-Library Download in das Projekt-Verzeichnis. Außerdem muss man die Datei &#039;&#039;&#039;&#039;&#039;Project\STM32F4xx_StdPeriph_Templates\stm32f4xx_conf.h&#039;&#039;&#039;&#039;&#039; ebenfalls aus dem Standard-Peripheral-Library Download in den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projektes kopieren. In der IDE fügt man den Include-Path &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\inc&#039;&#039;&#039;&#039;&#039; hinzufügen, wie bei der CMSIS-Library (s.o.).&lt;br /&gt;
Außerdem muss noch &#039;&#039;&#039;&#039;&#039;USE_STDPERIPH_DRIVER&#039;&#039;&#039;&#039;&#039; als Define in der IDE hinzugefügt werden (s.o.).&lt;br /&gt;
Danach fügt man die Source- und Include-Dateien aus dem Ordner &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\inc&#039;&#039;&#039;&#039;&#039; und &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\src&#039;&#039;&#039;&#039;&#039; dem Project mit &#039;&#039;&#039;&#039;&#039;&amp;lt;Project Name&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Add files&#039;&#039;&#039;&#039;&#039; hinzu, allerdings nur die, für welche auch der Controller die entsprechende Peripherie besitzt. Beim STM32F4-Discovery Board / STM32F407VG Controller dürfen also nicht folgende Dateien nicht mit hinzugefügt werden, weil diese Peripherie nur bei anderen Controller vorhanden ist:&lt;br /&gt;
&lt;br /&gt;
*stm32f4xx_dma2d.c/.h&lt;br /&gt;
*stm32f4xx_fmc.c/.h&lt;br /&gt;
*stm32f4xx_ltdc.c/.h&lt;br /&gt;
*stm32f4xx_sai.c/.h&lt;br /&gt;
&lt;br /&gt;
Daraus resultiert folgende Struktur:&lt;br /&gt;
&lt;br /&gt;
[[Datei:stdperiphlib_2.png|Header-Struktur]] [[Datei:stdperiphlib_1.png|Source-Struktur]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Anschließen kann die Standard-Peripheral-Library benutz werden.&lt;br /&gt;
main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);&lt;br /&gt;
&lt;br /&gt;
    GPIO_InitTypeDef GPIOD_InitStructure;&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Mode = GPIO_Mode_OUT;&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Pin = GPIO_Pin_15;&lt;br /&gt;
    GPIO_Init(GPIOD, &amp;amp;GPIOD_InitStructure);&lt;br /&gt;
&lt;br /&gt;
    GPIO_SetBits(GPIOD, GPIO_Pin_15);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Booten aus dem SRAM==&lt;br /&gt;
STM32 Controller haben die Möglichkeit Code aus dem Flash als auch aus dem SRAM auszuführen. Um eine Anwenung per Debugger in des SRAM zu laden sind nur wenige Schritte erforderlich:&lt;br /&gt;
&lt;br /&gt;
*Um das Linkerscript für den SRAM zu verwenden geht man zu: &#039;&#039;&#039;&#039;&#039;Build options... -&amp;gt; Device&#039;&#039;&#039;&#039;&#039; dort wählt man unter &#039;&#039;&#039;&#039;&#039;Policy&#039;&#039;&#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;Use target settings&#039;&#039;&#039;&#039;&#039; aus und übernimmt die vorherigen Einstellungen, nur unter &#039;&#039;&#039;&#039;&#039;Linker script*&#039;&#039;&#039;&#039;&#039; gibt man &#039;&#039;&#039;&#039;&#039;.\stm32f407vg_sram.ld&#039;&#039;&#039;&#039;&#039; an&lt;br /&gt;
&lt;br /&gt;
*Dann muss man noch unter &#039;&#039;&#039;&#039;&#039;Debug -&amp;gt; Interfaces -&amp;gt; Settings&#039;&#039;&#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;Vector table start&#039;&#039;&#039;&#039;&#039; auf 0x20000000 ändern und &#039;&#039;&#039;&#039;&#039;Execute from RAM&#039;&#039;&#039;&#039;&#039; auswählen.&lt;br /&gt;
&lt;br /&gt;
Anschließend kann man die Anwendung ganz normal debuggen. Nach einem Reset muss die Anwenung erneut mit dem Debugger gestartet werden.&lt;br /&gt;
&lt;br /&gt;
=Fortsetzung folgt..=&lt;br /&gt;
Kritik, Wünsche usw. sind gerne erwünscht, am besten hier in den Thread posten: [http://www.mikrocontroller.net/topic/323750 Neues STM32 Tutorial]&lt;br /&gt;
&lt;br /&gt;
[[Category:ARM]]&lt;br /&gt;
[[Category:STM32]]&lt;/div&gt;</summary>
		<author><name>Avrprogger</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=STM32_-_Einstieg_mit_Em::Blocks&amp;diff=81492</id>
		<title>STM32 - Einstieg mit Em::Blocks</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=STM32_-_Einstieg_mit_Em::Blocks&amp;diff=81492"/>
		<updated>2014-02-09T18:39:04Z</updated>

		<summary type="html">&lt;p&gt;Avrprogger: uzt&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In diesem Tutorial werde ich versuchen, möglichst einfach, die ersten Schritte zur Entwicklung von STM32 Anwenungen mit der Em::Blocks IDE zu erklären. Hier soll nicht so stark auf die einzelnen Peripherie-Module der Controller eingegangen werden, sondern mehr auf die IDE und die verschieden Libraries, wie die CMSIS Library, die DSP-Library, die Standard-Peripheral-Library, die USB-Library und vllt. über Ethernet. Ich denke ein Kapitel zu FreeRTOS wird es auch geben. Auserdem steht im Vordergrund Sachen wie z.B. booten aus dem SRAM, In-Application-Programming, FPU, Core-Coupled-RAM usw. Mal sehn wie weit ich komme ;)&lt;br /&gt;
&lt;br /&gt;
==Die Entwicklungsumgebung==&lt;br /&gt;
===Hardware===&lt;br /&gt;
Zum testen der Anwendungen, benutze ich das STM32F4-Discovery Board, welches einen Debugger, Peripherie und natürlich einen STM32 Controller (STM32F407VGT6) enthält. Deshalb sind alle Beispiele hier für den STM32F407VG Controller ausgelegt, können aber meisten 1:1 auf andere Controller portiert werden. Ich werde auch möglichsts keine STM32F4-Discovery Board spezifischen Libraries verwenden, damit der Portierungs-Vorgang möglichsts einfach bleibt.&lt;br /&gt;
&lt;br /&gt;
===Software===&lt;br /&gt;
In diesem Tutorial verwende ich [http://www.emblocks.org/ Em::Blocks] als IDE. Em::Blocks ist eine kostenlose, uneingeschränkte IDE, die alle STM32 Mikrcontroller unterstützt und sehr einfach zu bedienen ist.&lt;br /&gt;
nach dem Download kann die IDE per Dialog, sehr einfach, installiert werden. Als Compiler beinhaltet Em::Blocks den &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
Die IDE unterstützt zurzeit den ST-Link, den J-Link und es gibt eine Generic-Vorlage, durch welche andere Debugger konfiguriert werden können.&lt;br /&gt;
&lt;br /&gt;
Außerdem muss noch der passende Treiber für den Debugger installiert werden. Verwendet man ein Discovery-Board muss der [http://www.st.com/web/catalog/tools/FM146/CL1984/SC724/SS1677/PF251168 ST-Link/V2]-Treiber heruntergeladen und installiert werden. (Die Installation muss evtl. als Administrator ausgeführt werden, da sonst die Installation unvollständig wird.) Nach der Installation des Treibers kann man den Debugger über die entsprechende USB Schnittstelle an den PC anschließen und es sollte die Meldung von Windows kommen, dass der richtige Treiber gefunden wurde.&lt;br /&gt;
&lt;br /&gt;
===Libraries===&lt;br /&gt;
Zum programmieren benötigt man noch die [http://www.arm.com/products/processors/cortex-m/cortex-microcontroller-software-interface-standard.php CMSIS] und die Standard-Peripheral-Library (z.B. für die F4 Controller [http://www.st.com/stonline/stappl/productcatalog/app?page=partNumberSearchPage&amp;amp;levelid=SS1577&amp;amp;parentid=1743&amp;amp;resourcetype=SW Standard-Peripheral-Library-F4]), die man am besten in einen Ordner (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\STM32&#039;&#039;&#039;&#039;&#039;) entpackt&lt;br /&gt;
&lt;br /&gt;
==Basis-Wissen zur IDE==&lt;br /&gt;
Einige Grundfunktionalitäten der IDE:&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von Dateien zum Projekt===&lt;br /&gt;
Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf &amp;lt;ProjektName&amp;gt; -&amp;gt; Add files...&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Enfernen von Dateien aus dem Projekt===&lt;br /&gt;
Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf die Datei / mehrere Dateien auswählen -&amp;gt; Remove file from project&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
Die Dateien werden lediglich aus dem Projekt entfernt und nicht von der Festplatte gelöscht.&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von Include-Pfaden===&lt;br /&gt;
Sofern die Include-Datei(en) nicht im standard Include-Ordner &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; des Projektes liegen, muss man den Pfad zum Projekt hinzufügen, damit der Compiler die Include-Dateien später auch finden kann. Man geht wie folgt vor: Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf &amp;lt;ProjektName&amp;gt; -&amp;gt; Build options... -&amp;gt; Search Directories -&amp;gt; Add&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Compilieren===&lt;br /&gt;
Entweder über das &#039;&#039;&#039;&#039;&#039;Build&#039;&#039;&#039;&#039;&#039; Menü oder über &#039;&#039;&#039;&#039;&#039;F7&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Um eine genau Ausgabe des Compiler-Aufrufes mit allen Argumenten zu bekommen, geht man im &#039;&#039;&#039;&#039;&#039;Settings&#039;&#039;&#039;&#039;&#039; Menü auf &#039;&#039;&#039;&#039;&#039;Tools...&#039;&#039;&#039;&#039;&#039; und dann auf &#039;&#039;&#039;&#039;&#039;Toolchain executables&#039;&#039;&#039;&#039;&#039;. Ganz unten, unter &#039;&#039;&#039;&#039;&#039;Logging&#039;&#039;&#039;&#039;&#039; kann man dann &#039;&#039;&#039;&#039;&#039;Full command line&#039;&#039;&#039;&#039;&#039; auswählen.&lt;br /&gt;
&lt;br /&gt;
===Debuggen===&lt;br /&gt;
*Als erstes den Debugger starten über das &#039;&#039;&#039;&#039;&#039;Debug&#039;&#039;&#039;&#039;&#039; Menü und &#039;&#039;&#039;&#039;&#039;Start/stop Debug Session&#039;&#039;&#039;&#039;&#039; oder über &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
*Danach läuft die Anwendung auf dem Controller und warten im &#039;&#039;&#039;&#039;&#039;Reset_Handler&#039;&#039;&#039;&#039;&#039; auf Einzelschritt- bzw. Run- Befehle (&#039;&#039;&#039;&#039;&#039;F5, F10, F11&#039;&#039;&#039;&#039;&#039; usw..(siehe &#039;&#039;&#039;&#039;&#039;Debug-Menü&#039;&#039;&#039;&#039;&#039; für alle Möglichkeiten))&lt;br /&gt;
&lt;br /&gt;
*Mit &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039; wird die Debug-Session auch wieder beendet&lt;br /&gt;
&lt;br /&gt;
*Unter &#039;&#039;&#039;&#039;&#039;Debug -&amp;gt; Interfaces -&amp;gt; Target settings&#039;&#039;&#039;&#039;&#039; können Eigenschaften, wie z.B &#039;&#039;&#039;&#039;&#039;Run to main()&#039;&#039;&#039;&#039;&#039; aktiviert werden.&lt;br /&gt;
&lt;br /&gt;
===Projekt als Template abspeichern===&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;File -&amp;gt; Save project as template...&#039;&#039;&#039;&#039;&#039;. Das Template erscheint dann im Projekt-Dialog unter &#039;&#039;&#039;&#039;&#039;User templates&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Das erste Projekt erstellen==&lt;br /&gt;
Hier erkläre ich, wie man am Besten (aus meiner Sicht), ein neues Projekt von Grund auf erstellt, sodass man hinterher, den Controller-Kern über die CMSIS-Library und die Peripherie über die Register steuern kann.&lt;br /&gt;
&lt;br /&gt;
===1. Projekt mit der IDE erstellen===&lt;br /&gt;
Nach der Installation der oben beschriebenen Komponenten erstellt man am besten ein Verzeichnis (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\EmBlocks&#039;&#039;&#039;&#039;&#039;), indem später alle Projekte gespeichert werden. Für Libraries kann man auch noch ein Verzeichnis (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\STM32&#039;&#039;&#039;&#039;&#039;) erstellen, wo alle Libraries gespeichert werden, die man für die Projekt brauchen.&lt;br /&gt;
&lt;br /&gt;
Als nächstes starten man EmBlocks. Bei dem ersten Start öffnet sich ein Fenster, wo verschiedene Compiler angezeigt werden, die Em::Blocks findet. Dort wählt man den &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039; aus und klickt &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039;. Nun sollte sich das Hauptfenster von Em::Blocks öffnen. Über &#039;&#039;&#039;&#039;&#039;Create a new Project&#039;&#039;&#039;&#039;&#039; oder &#039;&#039;&#039;&#039;&#039;File -&amp;gt; New -&amp;gt; Project&#039;&#039;&#039;&#039;&#039; ruft man den Projekt-Dialog auf und kann ein neues Projekt erzeugen.&lt;br /&gt;
&lt;br /&gt;
Auf der Ersten Seite wählen man den &#039;&#039;&#039;&#039;&#039;STmicro-ARM&#039;&#039;&#039;&#039;&#039; Projekt-Typ aus.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_1.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auf der nächsten Seite wird man darauf hingewiesen, dass das der entsprechende Projekt-Typ-Dialog ausgeführt wird. Hier kann man ein Häkchen bei &#039;&#039;&#039;&#039;&#039;Skip this page next time&#039;&#039;&#039;&#039;&#039; setzen und auf &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; klicken.&lt;br /&gt;
&lt;br /&gt;
Im nächsten Schritt wählen man das zuvor erstellt Verzeichnis unter &#039;&#039;&#039;&#039;&#039;Folder to create Project in&#039;&#039;&#039;&#039;&#039; aus, indem später alle Projekt gespeichert werden. Außerdem geben wir dem Projekt einen Namen (z.B. &#039;&#039;&#039;&#039;&#039;FirstProject&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_2.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danach muss man einen Compiler auswählen und bestimmen, welche Projekt-Konfigurationen erszeugt werden sollen. Unter &#039;&#039;&#039;&#039;&#039;Compiler&#039;&#039;&#039;&#039;&#039; wählt man &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039; und man kann das Häkchen bei &#039;&#039;&#039;&#039;&#039;Create &amp;quot;Release&amp;quot; configuration&#039;&#039;&#039;&#039;&#039; entfernen, da diese unnötig ist, die Debug-Konfiguration sollte eig. immer ausreichen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_3.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auf den folgenden Seite wird der Controller ausgewählt. Verwendet man ein STM32F4-Discovery Board müssen folgende Dinge gewählt werden: &#039;&#039;&#039;&#039;&#039;Cortex_M4 (F3xx - F4xx) -&amp;gt; STM32F4xx (Cortex M4 with FPU) -&amp;gt; STM32F407VG&#039;&#039;&#039;&#039;&#039;. Leider sind die Auswahl Möglichkeiten nicht ganz richtig, da auch die F3 Controller einen Cortex M4 Kern und eine FPU haben (Ist aber nicht so wichtig, ist nur eine formale Sache). Außerdem entfernt man das Häkchen bei &#039;&#039;&#039;&#039;&#039;Standard Peripherals Library&#039;&#039;&#039;&#039;&#039; (Wie man die Standard-Peripheral-Library einbindet und verwendet erkläre ich später). Man kann auch das Häkchen bei &#039;&#039;&#039;&#039;&#039;Create hex file for Realease target&#039;&#039;&#039;&#039;&#039; entfernen.&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;Stack Size&#039;&#039;&#039;&#039;&#039; und &#039;&#039;&#039;&#039;&#039;Heap Size&#039;&#039;&#039;&#039;&#039; wird die Größe von Stack und Heap festgelegt. Für eine erste Anwendung kann man die Einstellungen so lassen (Stack-Size: 0x0100 =&amp;gt; 256 Byte Stack und Heap-Size: 0x0000 =&amp;gt; kein Heap). Mit &#039;&#039;&#039;&#039;&#039;Finish&#039;&#039;&#039;&#039;&#039; ist der Projekt Dialog abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_4.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danach sollten sich zwei neue Fenster öffnen, um die Debug-Eigenschaften fest zu legen.&lt;br /&gt;
Verwendet man ein Discovery Board/ST-Link müssen die Einstellungen wie auf dem Bild gewählt werden. Über den Button &#039;&#039;&#039;&#039;&#039;Settings&#039;&#039;&#039;&#039;&#039; öffnet sich das zweite Fenster, falls sich dieses nicht schon von alleine öffnen sollte. Nach den Schließen der Fenster über &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; ist der Projekt Dialog beendet und ein neues Projekt steht zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_5_1.png|Debug Eigenschaften 1. Fenster]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_5_2.png|Debug Eigenschaften 2. Fenster]]&lt;br /&gt;
&lt;br /&gt;
===2. CMSIS-Library und Startup-Code hinzufügen===&lt;br /&gt;
Wenn man sich, nachdem man ein neues Projekt in der IDE erstellt hat, die bereits vorhandenen Dateien im Projekt ansieht, stellt man fest, das bereits ein Ordner &#039;&#039;&#039;&#039;&#039;cmsis&#039;&#039;&#039;&#039;&#039; existiert, der einige wichtige Include-Dateien der CMSIS-Library enthält. Allerdings sind das wirklich nur die wichtigsten Include-Dateien der CMSIS-Library und dazu noch, die aus einer älternen Version. Ich ziehe es deshalb vor die &amp;quot;Mini-CMSIS-Libraray&amp;quot; und die &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c/.h&#039;&#039;&#039;&#039;&#039; Dateien des Projektes durch aktuellere Versionen zu ersetzen. So ist später auch die Integration  von anderen Libraries, wie z.B. der CMSIS-DSP-Libarary einfacher.  &lt;br /&gt;
&lt;br /&gt;
Zunächst gehen man in das Projekt-Verzeichnis und löscht:&lt;br /&gt;
*Den Ordner &#039;&#039;&#039;&#039;&#039;cmsis&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Alle Dateien im Include Verzeichnis &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; im &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner&lt;br /&gt;
&lt;br /&gt;
Außerdem entfernt man auch alle gelöschten Dateien in der IDE aus dem Projekt mit &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Rechts Klick -&amp;gt; Remove file from project&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Es sollte folgende Verzeichnis Struktur überbleiben:&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_6.png|Überbleibende Dateien]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Jetzt müssen die gelöschten Dateien durch die aktuelleren ersetzt werden.&lt;br /&gt;
&lt;br /&gt;
*Dazu kopieren man den gesamten Ordner &#039;&#039;&#039;&#039;&#039;CMSIS&#039;&#039;&#039;&#039;&#039; aus dem CMSIS Download in das Projekt Verzeichnis.&lt;br /&gt;
&lt;br /&gt;
*Aus dem Standard-Peripheral-Library Download kopiert man von &#039;&#039;&#039;&#039;&#039;Libraries\CMSIS\Device\ST\STM32F4xx\Include&#039;&#039;&#039;&#039;&#039; alle Dateien in den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projekt Verzeichnisses&lt;br /&gt;
&lt;br /&gt;
*Aus der Standard-Peripheral-Library kopieren man ebenfalls von &#039;&#039;&#039;&#039;&#039;Libraries\CMSIS\Device\ST\STM32F4xx\Source\Templates&#039;&#039;&#039;&#039;&#039; die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; in den &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner des Projekts&lt;br /&gt;
&lt;br /&gt;
Anschließend müssen die neuen Dateien in der IDE dem Projekt hinzugefügt werden. Dazu benutzt man &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Rechts Klick -&amp;gt; Add files&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
*Aus dem &#039;&#039;&#039;&#039;&#039;CMSIS&#039;&#039;&#039;&#039;&#039; Ordner im Projekt Verzeichnis werden aus den Unterorder &#039;&#039;&#039;&#039;&#039;Include&#039;&#039;&#039;&#039;&#039; folgende Dateien dem Projekt hinzugefügt:&lt;br /&gt;
**arm_common_tables.h&lt;br /&gt;
**arm_const_structs.h&lt;br /&gt;
**arm_math.h&lt;br /&gt;
**core_cm4.h&lt;br /&gt;
**core_cm4_simd.h&lt;br /&gt;
**core_cmFunc.h&lt;br /&gt;
**core_cmInstr.h&lt;br /&gt;
*Alle Dateien aus den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projektes&lt;br /&gt;
*Die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; aus dem &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner&lt;br /&gt;
&lt;br /&gt;
So sollte die Struktur dann aussehen:&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_7.png|Anwenungs-Grundgerüst]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Da einige Dateien der Libraries später bearbeitet werden müssen und Schreibgeschützt sind, weise ich hier schonmal darauf hin, das der Schreibschutz in der IDE über &#039;&#039;&#039;&#039;&#039;Rechts Klick auf die Datei -&amp;gt; Properties -&amp;gt; Häkchen bei &amp;quot;File is read only&amp;quot; entfernen&#039;&#039;&#039;&#039;&#039; entfert werden kann.&lt;br /&gt;
&lt;br /&gt;
Damit die IDE die Header-Dateien der CMSIS Library auch finden kann, weil diese ja nicht im standard Include Ordner &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; liegen, muss unter &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Build Options -&amp;gt; Search Directories&#039;&#039;&#039;&#039;&#039; der Pfad &#039;&#039;&#039;&#039;&#039;CMSIS\Include&#039;&#039;&#039;&#039;&#039; hinzugefügt werden.&lt;br /&gt;
&lt;br /&gt;
Compiliert man jetzt das Projekt mit &#039;&#039;&#039;&#039;&#039;F7&#039;&#039;&#039;&#039;&#039; gibt es ein paar Fehler Meldungen, weil keine Controller-Reihe ausgewählt wurde. Ebenfalls unter &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Build Options -&amp;gt; Compiler Settings -&amp;gt; #defines&#039;&#039;&#039;&#039;&#039; wird der Define &#039;&#039;&#039;&#039;&#039;STM32F40_41xxx&#039;&#039;&#039;&#039;&#039; hinzugefügt.&lt;br /&gt;
&lt;br /&gt;
Beim erneuten Compilieren sollten sich nun keine neuen Fehler ergeben.&lt;br /&gt;
&lt;br /&gt;
===Das erste Programm===&lt;br /&gt;
Nachdem ein grundsätzliches &amp;quot;Gerüst&amp;quot; fertig ist, kann man den ersten Code schreiben.&lt;br /&gt;
main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC-&amp;gt;AHB1ENR |= RCC_AHB1ENR_GPIODEN;    //Takt für GPIO aktivieren&lt;br /&gt;
    GPIOD-&amp;gt;MODER |= GPIO_MODER_MODER15_0;   //GPIOD Pin15 als Ausgang&lt;br /&gt;
    GPIOD-&amp;gt;BSRRL |= GPIO_BSRR_BS_15;        //GPIOD Pin15 auf High ziehen&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Download: [[Datei:FirstProject.zip]]&lt;br /&gt;
&lt;br /&gt;
Mit &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039; wird dann der Debugger gestartet. Hat der Debugger das Projekt erfolgreich übertragen kann die Ausführung mit &#039;&#039;&#039;&#039;&#039;F5&#039;&#039;&#039;&#039;&#039; begonnen werden.&lt;br /&gt;
&lt;br /&gt;
==Takt, FPU usw.==&lt;br /&gt;
===Der Takt===&lt;br /&gt;
Jeder Controller oder Prozessor braucht einen Takt, indem er die einzelnen Maschinen-Befehle abarbeiten kann.&lt;br /&gt;
Bei den STM32 Mikrocontrollern kann dieser Takt aus verschiedenen Quellen kommen:&lt;br /&gt;
&lt;br /&gt;
1. High Speed Internal Oszillator (HSI)&lt;br /&gt;
&lt;br /&gt;
2. High Speed External Oszillator (HSE)&lt;br /&gt;
&lt;br /&gt;
3. Low Speed Internal Oszillator (LSI)&lt;br /&gt;
&lt;br /&gt;
4. Low Speed External Oszillator (LSE)&lt;br /&gt;
&lt;br /&gt;
5. Phase-Locked Loop (PLL) (generiert den Takt aus den ersten vier Taktquellen durch Teiler und Faktoren)&lt;br /&gt;
&lt;br /&gt;
Nach einem Reset wird der Controller aus der HSI Taktquelle versorgt (16MHz beim STM32F407VG). Um die voll Performance des Controllers zu erreichen muss die PLL verwendet werden, welche den Takt durch geschickte Teiler und Faktoren vervielfältigt, sodass am Ende der Controller mit der maximalen Taktfrequenz läuft. Die notwendige Initialisierung der PLL findet in der Funktion &#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; statt. Die PLL erzeugt zunächst einen Basistakt:&lt;br /&gt;
&lt;br /&gt;
PLL_VCO = (F_HSE / PLL_M) * PLL_N&lt;br /&gt;
&lt;br /&gt;
Aus diesem Takt wird dann der Takt für den Controller-Kern abgeleitet:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = PLL_VCO / PLL_P&lt;br /&gt;
&lt;br /&gt;
Und der Takt für SDIO / USB / RNG (48MHz):&lt;br /&gt;
&lt;br /&gt;
48MHz = PLL_VCO / PLL_Q&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Durch weiter Teiler werden, die Takte für die einzelnen Busse erzeugt, da diese nicht alle beliebig schnell betrieben werden dürfen.&lt;br /&gt;
&lt;br /&gt;
Genaue Angaben findet man zu dem jeweiligen Clock-System des Controllers im Reference Manual.&lt;br /&gt;
&lt;br /&gt;
Ein Blick in den &amp;quot;Kommentar-Header&amp;quot; verrät, dass von einem externen (HSE) Oszillator von 25MHz ausgegangen wird, der die PLL versorgen soll.&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((25MHz / PLL_M(25)) * PLL_N(336)) / PLL_P(2) = 168MHz&lt;br /&gt;
&lt;br /&gt;
Allerdings stimmt diese Rechnung natürlich nur, wenn wirklich ein 25MHz Quarz am Controller angeschlossen ist. Auf dem STM32F4-Discovery Board befindet sich aber nur ein 8MHz Quarz. Demnach gilt:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((8MHz / PLL_M(25)) * PLL_N(336)) / PLL_P(2) = 53.76MHz&lt;br /&gt;
&lt;br /&gt;
Der Controller läuft also nur mit 53.76MHz, wenn wie ober beschrieben ein Projekt erstellt wird. Allerdings kann dieses Problem durch ändern von den betroffen Defines behoben werden:&lt;br /&gt;
 &lt;br /&gt;
*Dazu geht man in die &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; Datei und passt zur Vollständigkeit erstmal die zum Controller passende Tabelle im &amp;quot;Kommentar-Header&amp;quot; an (Z.57f):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      HSE Frequency(Hz)                      | 8000000&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      PLL_M                                  | 8&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Danach passt man den PPL_M Define (Z.254) an:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/************************* PLL Parameters *************************************/&lt;br /&gt;
/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */&lt;br /&gt;
#define PLL_M      8&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Außerdem muss man den HSE_VALUE Define in der &#039;&#039;&#039;&#039;&#039;inc/stm32f4xx.h&#039;&#039;&#039;&#039;&#039; angepasst werden (Z.122):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#if !defined  (HSE_VALUE)&lt;br /&gt;
  #define HSE_VALUE    ((uint32_t)8000000) /*!&amp;lt; Value of the External oscillator in Hz */&lt;br /&gt;
&lt;br /&gt;
#endif /* HSE_VALUE */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine neue Berechnung zeigt:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((8MHz / PLL_M(8)) * PLL_N(336)) / PLL_P(2) = 168MHz&lt;br /&gt;
&lt;br /&gt;
Jetzt läuft der Controller mit maximaler Geschwindigkeit.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Achtung!:&lt;br /&gt;
In dem &amp;quot;Kommentar-Header&amp;quot; der &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; steht in der letzten Zeile immer:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      Require 48MHz for USB OTG FS,          | Disabled&lt;br /&gt;
*      SDIO and RNG clock                     |&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das ist jedoch falsch, weil der Takt für USB, SDIO und RNG immer mit der PLL über den Teiler PPL_Q eingestellt wird. Der Takt ist somit immer vorhanden und muss nicht extra Eingeschaltet werden. (Erspart langes Suchen, nach den entsprechenden Registern)&lt;br /&gt;
&lt;br /&gt;
===Die FPU===&lt;br /&gt;
====Allgemeines====&lt;br /&gt;
Damit die FPU richtig verwendet wird, müssen normalerweise zwei Bedingungen erfüllt sein:&lt;br /&gt;
&lt;br /&gt;
1. Der Controller muss in der Initialisierung-Funktion &#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; in &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; die FPU Hardware-seitig aktivieren&lt;br /&gt;
&lt;br /&gt;
2. Damit die FPU auch was zu tuen bekommt, müssen vom Compiler FPU-Instructions erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
Die Em::Blocks IDE verwendet standardmäßig die FPU, wenn eine Vorhanden ist. Hier wird die FPU Hardware-seitig aktiviert (&#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; Z.341):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* FPU settings ------------------------------------------------------------*/&lt;br /&gt;
  #if (__FPU_PRESENT == 1) &amp;amp;&amp;amp; (__FPU_USED == 1)&lt;br /&gt;
    SCB-&amp;gt;CPACR |= ((3UL &amp;lt;&amp;lt; 10*2)|(3UL &amp;lt;&amp;lt; 11*2));  /* set CP10 and CP11 Full Access */&lt;br /&gt;
  #endif&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
__FPU_PRESENT wird in der &#039;&#039;&#039;&#039;&#039;stm32f4xx.h&#039;&#039;&#039;&#039;&#039; definiert.&lt;br /&gt;
__FPU_USED wird von der IDE übernommen (siehe Build-Log): &#039;&#039;&#039;&#039;&#039;-D__FPU_USED&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Außerdem wird der Compiler von der IDE standardmäßig mit dem Argument &#039;&#039;&#039;&#039;&#039;-mfloat-abi=hard&#039;&#039;&#039;&#039;&#039; aufgerufen, wodurch FPU-Instructions erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
====FPU abschalten====&lt;br /&gt;
Um die FPU ab zu schalten (Mir würde jetzt nur Strom sparen als Grund einfallen) geht man wie folgt vor:&lt;br /&gt;
&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick Build options -&amp;gt; Device -&amp;gt; Policy&#039;&#039;&#039;&#039;&#039; wählt man &#039;&#039;&#039;&#039;&#039;Use target settings&#039;&#039;&#039;&#039;&#039; und über nimmt die Einstellungen, die vorher dort eingetragen waren, allerdings lässt man das Feld &#039;&#039;&#039;&#039;&#039;FP-hardware&#039;&#039;&#039;&#039;&#039; frei.&lt;br /&gt;
&lt;br /&gt;
[[Datei:fpu_1.png|FPU Abschalten Schritt 1]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;Compiler Settings -&amp;gt; Policy&#039;&#039;&#039;&#039;&#039; wählt man dann &#039;&#039;&#039;&#039;&#039;Use target options only&#039;&#039;&#039;&#039;&#039;. Dann kann man unter &#039;&#039;&#039;&#039;&#039;Categories&#039;&#039;&#039;&#039;&#039; die Option &#039;&#039;&#039;&#039;&#039;ARM FPU architecture&#039;&#039;&#039;&#039;&#039; auswählen. Dort stehen dann drei Möglichkeiten für die FPU zur Verfügung:&lt;br /&gt;
&lt;br /&gt;
1. Software-FPU-Library für Gleitkomma-Berechnung verwenden - Keine FPU-Instructions werden generiert (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=soft&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
2. Eine Mischung aus Software- und Hardware-FPU wird verwendet (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=softfp&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
3. Hardware-FPU wird für Gleitkomma-Berechnungen verwendet (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=hard&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
[[Datei:fpu_2.png|FPU Abschalten Schritt 2]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Um die FPU ab zu schalten wählt man natürlich die erste Möglichkeit.&lt;br /&gt;
Bei der 2. und 3. Möglichkeit fügt die IDE auch den Define &#039;&#039;&#039;&#039;&#039;__FPU_USED&#039;&#039;&#039;&#039;&#039; hinzu. Bei Der ersten Möglichkeit nicht. Der Code muss also nicht verändert / auskommentiert werden.&lt;br /&gt;
&lt;br /&gt;
Um die FPU wieder zu aktivieren müssen alle Schritte wieder rückgängig gemacht werden.&lt;br /&gt;
&lt;br /&gt;
Am besten ist es einfach mal alle Möglichkeiten im Einzelschritt durch zu probieren. Dann stellt man schnell fest, ob die FPU aktiviert wir oder nicht. Ein Blick in den erweiterten &#039;&#039;&#039;&#039;&#039;Build-Log&#039;&#039;&#039;&#039;&#039; gibt auch schnell Aufschluss darüber, wie der Compiler aufgerufen wird (siehe Kapitel [http://www.mikrocontroller.net/articles/STM32_-_Einstieg_mit_Em::Blocks#Compilieren Compilieren]).&lt;br /&gt;
&lt;br /&gt;
====Test Programm für die FPU====&lt;br /&gt;
Hier ein kleines Testprogramm, dass misst wie viele Taktzyklen für eine Gleitkomma-Multiplikation gebraucht werden. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define CORE_SysTickEn()    (*((u32*)0xE0001000)) = 0x40000001&lt;br /&gt;
#define CORE_SysTickDis()   (*((u32*)0xE0001000)) = 0x40000000&lt;br /&gt;
#define CORE_GetSysTick()   (*((u32*)0xE0001004))&lt;br /&gt;
&lt;br /&gt;
uint32_t t1, t2, dt;&lt;br /&gt;
float x, y, z;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    x = 53.64f;&lt;br /&gt;
    y = 0.27f;&lt;br /&gt;
&lt;br /&gt;
    CORE_SysTickEn();&lt;br /&gt;
    t1 = CORE_GetSysTick();&lt;br /&gt;
&lt;br /&gt;
    z = x * y;&lt;br /&gt;
&lt;br /&gt;
    t2 = CORE_GetSysTick();&lt;br /&gt;
    CORE_SysTickDis();&lt;br /&gt;
&lt;br /&gt;
    dt = t2 - t1;&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mein Ergebnis:&lt;br /&gt;
*Mit Hardware-FPU:  dt = 25&lt;br /&gt;
*Ohne Hardware-FPU: dt = 83&lt;br /&gt;
&lt;br /&gt;
Download: [[Datei:FPU_Test.zip]]&lt;br /&gt;
&lt;br /&gt;
==Einbinden der Standard Peripheral Library==&lt;br /&gt;
Um nicht immer die einzelnen Register, wie im ersten &amp;quot;bare-metal&amp;quot; Beispiel, aus dem Reference-Manual zu suchen und zu beschreiben, gibt es von ST die Standard Peripheral Library, die diese Aufgaben übernimmt und mit der sich die &amp;quot;normale/grundlegende&amp;quot; (Alles außer USB und Ethernet) Peripherie recht einfach steuern lässt. Um die Library zu verwenden erzeugt man wie oben beschrieben ein neues Grundgerüst und kopiert als erstes den Ordner &#039;&#039;&#039;&#039;&#039;Libraries\STM32F4xx_StdPeriph_Driver&#039;&#039;&#039;&#039;&#039; aus dem Standard-Peripheral-Library Download in das Projekt-Verzeichnis. Außerdem muss man die Datei &#039;&#039;&#039;&#039;&#039;Project\STM32F4xx_StdPeriph_Templates\stm32f4xx_conf.h&#039;&#039;&#039;&#039;&#039; ebenfalls aus dem Standard-Peripheral-Library Download in den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projektes kopieren. In der IDE fügt man den Include-Path &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\inc&#039;&#039;&#039;&#039;&#039; hinzufügen, wie bei der CMSIS-Library (s.o.).&lt;br /&gt;
Außerdem muss noch &#039;&#039;&#039;&#039;&#039;USE_STDPERIPH_DRIVER&#039;&#039;&#039;&#039;&#039; als Define in der IDE hinzugefügt werden (s.o.).&lt;br /&gt;
Danach fügt man die Source- und Include-Dateien aus dem Ordner &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\inc&#039;&#039;&#039;&#039;&#039; und &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\src&#039;&#039;&#039;&#039;&#039; dem Project mit &#039;&#039;&#039;&#039;&#039;&amp;lt;Project Name&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Add files&#039;&#039;&#039;&#039;&#039; hinzu, allerdings nur die, für welche auch der Controller die entsprechende Peripherie besitzt. Beim STM32F4-Discovery Board / STM32F407VG Controller dürfen also nicht folgende Dateien nicht mit hinzugefügt werden, weil diese Peripherie nur bei anderen Controller vorhanden ist:&lt;br /&gt;
&lt;br /&gt;
*stm32f4xx_dma2d.c/.h&lt;br /&gt;
*stm32f4xx_fmc.c/.h&lt;br /&gt;
*stm32f4xx_ltdc.c/.h&lt;br /&gt;
*stm32f4xx_sai.c/.h&lt;br /&gt;
&lt;br /&gt;
Daraus resultiert folgende Struktur:&lt;br /&gt;
&lt;br /&gt;
[[Datei:stdperiphlib_2.png|Header-Struktur]] [[Datei:stdperiphlib_1.png|Source-Struktur]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Anschließen kann die Standard-Peripheral-Library benutz werden.&lt;br /&gt;
main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);&lt;br /&gt;
&lt;br /&gt;
    GPIO_InitTypeDef GPIOD_InitStructure;&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Mode = GPIO_Mode_OUT;&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Pin = GPIO_Pin_15;&lt;br /&gt;
    GPIO_Init(GPIOD, &amp;amp;GPIOD_InitStructure);&lt;br /&gt;
&lt;br /&gt;
    GPIO_SetBits(GPIOD, GPIO_Pin_15);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Download: [[Datei:StdPeriphLib_Project.zip]]&lt;br /&gt;
&lt;br /&gt;
==Booten aus dem SRAM==&lt;br /&gt;
STM32 Controller haben die Möglichkeit Code aus dem Flash als auch aus dem SRAM auszuführen. Um eine Anwenung per Debugger in des SRAM zu laden sind nur wenige Schritte erforderlich:&lt;br /&gt;
&lt;br /&gt;
*Um das Linkerscript für den SRAM zu verwenden geht man zu: &#039;&#039;&#039;&#039;&#039;Build options... -&amp;gt; Device&#039;&#039;&#039;&#039;&#039; dort wählt man unter &#039;&#039;&#039;&#039;&#039;Policy&#039;&#039;&#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;Use target settings&#039;&#039;&#039;&#039;&#039; aus und übernimmt die vorherigen Einstellungen, nur unter &#039;&#039;&#039;&#039;&#039;Linker script*&#039;&#039;&#039;&#039;&#039; gibt man &#039;&#039;&#039;&#039;&#039;.\stm32f407vg_sram.ld&#039;&#039;&#039;&#039;&#039; an&lt;br /&gt;
&lt;br /&gt;
*Dann muss man noch unter &#039;&#039;&#039;&#039;&#039;Debug -&amp;gt; Interfaces -&amp;gt; Settings&#039;&#039;&#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;Vector table start&#039;&#039;&#039;&#039;&#039; auf 0x20000000 ändern und &#039;&#039;&#039;&#039;&#039;Execute from RAM&#039;&#039;&#039;&#039;&#039; auswählen.&lt;br /&gt;
&lt;br /&gt;
Anschließend kann man die Anwendung ganz normal debuggen. Nach einem Reset muss die Anwenung erneut mit dem Debugger gestartet werden.&lt;br /&gt;
&lt;br /&gt;
=Fortsetzung folgt..=&lt;br /&gt;
Kritik, Wünsche usw. sind gerne erwünscht, am besten hier in den Thread posten: [http://www.mikrocontroller.net/topic/323750 Neues STM32 Tutorial]&lt;br /&gt;
&lt;br /&gt;
[[Category:ARM]]&lt;br /&gt;
[[Category:STM32]]&lt;/div&gt;</summary>
		<author><name>Avrprogger</name></author>
	</entry>
</feed>