STM32 LEDBlinken AtollicTrueStudio

Aus der Mikrocontroller.net Artikelsammlung, mit Beiträgen verschiedener Autoren (siehe Versionsgeschichte)
Wechseln zu: Navigation, Suche
Version:       07 Oktober 2010
Authoren:      Lukas Simma (Inexess Technology Simma KG)
               Norbert Kleber (Sensing Solutions)

Info:          Bitte Artikel verbessern und erweitern wenn gewünscht

IDE:           IDE Atollic Truestudio Lite 1.4 (Free)
                 Editor       Atollic - Eclipse 3.5
                 Toolchain    arm-atollic-eabi-gcc
                 Debugger     ST-LINK via Atollic gdbproxy für JTAG

Hardware:      Ein Test/Demoboard mit einem STM32F10x 
               (und mindestens eine schaltbare LED)
               hier STM3210C Demoboard mit STM32F107
               sowie ein Kundenboard mit STM32F103


Um den Einstieg zu erleichtern wird hier ein minimales Beispiel, eine blinkende LED, mithilfe der STM32 Std. Peripherial Library vorgestellt.

In diesem Beispiel möchte ich so gut wie das Minimum zeigen was nötig ist um mit der Std. Peripherie Library eine LED zum Blinken bringen.

(Für mich war auch lange nicht klar was als Minimum benötigt wird). Dass das Blinken (der delay) mit dem Systick vom Cortex-M3 schöner lösbar ist,

kommt dann in einem nächsten Intro incl. dem DeInit(). 

Hier also erst mal das Minimumbeispiel...

Verwendete Komponenten

  • IDE Atollic Truestudio Lite 1.4 (Free)
  • JTAG Debugger ST-LINK (ca. 25€)
  • Ein Test/Demoboard mit einem STM32F10x (und mindestens eine schaltbare LED)

Kompontenten herunterladen und installieren

Downloaden von Atollic TrueSTUDIO®/STM32 Lite (1.4)

und installieren.

Den ST-LINK updaten damit er neuere Controller kennt. Downloaden des "ST-Link firmware upgrade" von der ST Seite

http://www.st.com/mcu/familiesdocs-110.html. ST-Link am USB anstecken, ZIP-File Entpacken, ST-LinkUpgrade.exe ausführen, Button "Device Connect"

und "YES" anklicken um das update auszuführen.

Dokumentationen herunterladen

Von der ST Seite http://www.st.com/mcu/familiesdocs-110.html herunterladen von

  • RM0008 Reference Manual
  • Das zum Controller auf dem Board passende Datasheet
 (zb. "STM32F105/107xx" für den STM32F107)
  • PM0056 STM32F10xxx Cortex-M3 programming manual

C-Code Projekt für den Controller einrichten

TrueStudio starten und einen (neuen) Workspace Ordner wählen. Im Workspace Ordner wird pro Projekt dann ein Projektordner abgelegt.

Truestudio start workspace.png

Die Introseite beenden mit "Start using TrueSTUDIO" und ein neues C-Projekt erstellen mit File -> New -> C-Projekt.... wähle STM32 C Projekt ... Atollic ARM Tools

Truestudio new c project.jpg

Truestudio new c project wizard1.JPG

Nachfolgender Dialog definier welche Projekteinstellungen vorgenommen werden und welches Linkerscript und Startupfile in das Projekt kopiert wird.

Evaluation board: None Ausser der Std. Peripherial Library wollen wir keinen zusätzlichen Code hinzufügen

Microcontroller family und Microcontroller: Wähle hier den Controller der auf DEINEM EIGENEN Board bestückt ist.

Code location: FLASH -- das Programm wird dauerhaft in in internen Flash des STM32 abgelegt. RAM -- das Programm wird in den internen RAM geschrieben und

ist nach dem Abschalten des Stromes wieder futsch.

Nun den Finish Button drücken, das Projekt wird erstellt, die notwendigen Dateien erzeugt.

Truestudio new c project wizard2.JPG

Main Code für Blinking LED

Die Codefiles finden sich im Order src. Der vom Wizard erstellte Code im main.c wird durch folgenden Code ersetzt.

main.c:

#include "stm32f10x.h"

// Die Std. Peripherie arbeitet viel über Strukturen
// Struktur um PortPins zu initialisieren
GPIO_InitTypeDef GPIO_InitStructure;


void delayLoop() {
	volatile uint32_t delayCount = 1000000; // volatile, um "Wegoptimieren" zu vermeinden
                                                //(http://en.wikipedia.org/wiki/Volatile_variable)
	while (delayCount > 0) {
		delayCount--;
	}
}

int main(void)
{
	// Die Std. Peripherie nun Clocks, PLLs usw. einrichten
	SystemInit();

	// PORT D Peripherie aktivieren
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);

	// PortPin als Ausgang configurieren
	GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_7;       
	GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_Out_PP; 
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 
	GPIO_Init(GPIOD, &GPIO_InitStructure);            

	while(1) {
		GPIOD->BSRR = GPIO_Pin_7; // LED On
		delayLoop();

		GPIOD->BRR = GPIO_Pin_7;  // LED Off
		delayLoop();
	}
}

Projekt Builden

Das Projekt nun Builden mit dem Eintrag "Debug" beim Hammersymbol. Am unteren Rand gibt es die Problems view, hier dürfen keine Fehler aufscheinen.

In der Console View wird der Compile und Linkerablauf und das Ergebnis ausgegeben.

Wenn es klappt liegt nun das fertige File als LEDBlinken.elf im Ordner "Debug".

Truestudio compilieren.JPG


Configuration zum Flashen und Debuggen

Das File nun mit dem ST-Link über JTAG auf das Board flashen. Dazu muss erstmalig eine Debug Configuration eingerichtet werden. Klicke auf das Icon des

"Grünen Käfer" und selektiere "Debug As" --> "Embedded C/C++ Application". Der Wizard für eine neue Debug Configuration wird geöffnet, die Einstellungen für den ST-LINK sich korrekt eingetragen.

Mit Apply und OK wird die neuen Debug Configuration angelegt (elf File in den Controller flashen, debug starten, brakepoint ist erste zeile in main) Diese Debug Config ist nun direkt über

das Debug Icon "Grüner Käfer" erreichbar.

Truestudio flash and debug stlink first time.JPG

Truestudio flash and debug wizard.JPG

Truestudio debug session1.JPG

Workspace mit Projekt zum download

Falls es nicht klappt hier der Workspace mit dem Blinking LED Projekt drin.

TrueStudio/STM32 Workspace mit Blinking LED Projekt

Erklärungen zum Code

Notwendiger Include

  #include "stm32f10x.h"

Um mit der STM32 Standard Peripheral Library (STM32StdPerLib) zu arbeiten ist in den Code Files jeweils obiger Include einzubinden. Die gesamte Library liegt im Projekt im Ordner "firmware" und wird vom Compiler mitkompiliert.

  • Ordner: firmware/CMSIS
 Coretx-M3 spezifische Codes
  • Ordner: firmware/STM32F10x_StdPeriph_Driver
 STM32 Peripherie Codes

Die Code Files im Ordner "firmware" sollen -wenn möglich- nicht geändert werden. Von der STM32StdPerLib wird ein Configfile (stm32f10x_conf.h) eingebunden welches vom User geändert werden soll, das Headerfile ist nicht unter "firmware" zu finden sondern unter "src" bei den Userfiles.

  • File src/stm32f10x_conf.h
 Bindet die im Projekt verwendeten Peripherie Module ein. Es können alle Module aktiviert bleiben jedoch ist bei einem "Build all" dann die Compilezeit etwas länger. Durch die Optimierung dass unbenutzte Funktionen vom Linker entfernt werden hat es keine Auswirkungen auf die Codesize.

Alternative kann für dieses Beispiel der Include Block im stm32f10x_conf.h wie folgt auf zwei Module reduziert werden.

/* Uncomment the line below to enable peripheral header file inclusion */
// #include "stm32f10x_adc.h"
// #include "stm32f10x_bkp.h"
// #include "stm32f10x_can.h"
// #include "stm32f10x_cec.h"
// #include "stm32f10x_crc.h"
// #include "stm32f10x_dac.h"
// #include "stm32f10x_dbgmcu.h"
// #include "stm32f10x_dma.h"
// #include "stm32f10x_exti.h"
// #include "stm32f10x_flash.h"
// #include "stm32f10x_fsmc.h"
#include "stm32f10x_gpio.h"
// #include "stm32f10x_i2c.h"
// #include "stm32f10x_iwdg.h"
// #include "stm32f10x_pwr.h"
#include "stm32f10x_rcc.h"
// #include "stm32f10x_rtc.h"
// #include "stm32f10x_sdio.h"
// #include "stm32f10x_spi.h"
// #include "stm32f10x_tim.h"
// #include "stm32f10x_usart.h"
// #include "stm32f10x_wwdg.h"
// #include "misc.h" /* High level functions for NVIC and SysTick (add-on to CMSIS functions) */

Hier ein Bild wie die Library aufgebaut ist

Stm32 std peripherial library architecture.JPG

STM32 Initialisieren lassen

Einen STM32 (ARM Cortex-M3) zu initialisieren ist etwas aufwändiger da er mehrere interne Bussysteme hat und auch mehrere Clocks für die unterschiedlichen Peripheriebausteine erzeugen muss. Desweiteren wird der interne oder externe (Quartz) Takt mittels PLL multipliziert so dass der Core und die Peripherie auf einer höheren Frequenz arbeitet.

Siehe RM0008 Reference manual

 für Connection Linie (CL): Seite 115 (Figure 11. Clock tree)
 für die anderen Linien: Seite 84 (Figure 8. Clock tree)

Diese Initialisierung wird am besten der STM32StdPerLib überlassen. Dazu wird die Funtion SystemInit(); am Anfange der Main aufgerufen.

  SystemInit();

Da jedoch die Clocksettings für die verschiedenen Linie voneinander abweichen sind im Compiler Environment zwei Symbole zu definieren.

Truestudio symbole in projektsettings.JPG

  • STM32F10X_CL
 Definiert dass eine Controller aus der Connectin Line (STM32F107 oder STM32F105) verwendet wird.
  • USE_STDPERIPH_DRIVER
 Definiert dass die Module für die STM32 Peripherie aus der STM32StdPerLib verwendet werden können.

Siehe dazu im "stm32f10x.h" auf Zeile 48

Folgende Controller Settings sind möglich

#define STM32F10X_LD     STM32F10X_LD: STM32 Low density devices
#define STM32F10X_LD_VL  STM32F10X_LD_VL: STM32 Low density Value Line devices  
#define STM32F10X_MD     STM32F10X_MD: STM32 Medium density devices
#define STM32F10X_MD_VL  STM32F10X_MD_VL: STM32 Medium density Value Line devices  
#define STM32F10X_HD     STM32F10X_HD: STM32 High density devices
#define STM32F10X_XL      STM32F10X_XL: STM32 XL-density devices
#define STM32F10X_CL     STM32F10X_CL: STM32 Connectivity line devices

Stolperfalle Quartzfrequenz auf eigenen Boards

ACHTUNG: Um die STM32StdPerLib ohne Änderungen am Code zu nutzen darf nur jene Quarzfrequenz bei externen Quarzen (HSE) verwendet werden für welche die Lib auch ausgelegt wurde.

  • bei STM32F10X_CL: NUR 25MHz Quartz verwenden
  • bei allen anderen: NUR 8MHz Quartz verwenden

Siehe dazu im "stm32f10x.h" auf Zeile 92 und system_stm32f10x.c auf Zeile 977 hier ist ersichtlich dass die Configuration auf die obigen HSE Quartzfrequenzen geschrieben ist. Falls es kein Politikum gibt am besten die beiden Quartze verwenden, das erspart viele (sinnlose) Stunden.

Für CL compiliert jedoch anderen STM32 auf dem Board (und umgekehrt)

ACHTUNG: Die Connection Line hat einen andere internen Aufbau für PLL und Clocks. Ein Code der für die CL Line compiliert wurde und auf eine andere Linie geflasht wird (oder umgekehrt) hängt dann bei der Initialisierung der Clocks.

Siehe RM0008 Reference manual, beachte dass es ZWEI RCC Kapitel gibt

 Kapitel 6: Low-, medium-, high- and XL-density reset and clock control (RCC)
 Kapitel 7: Connectivity line devices: reset and clock control (RCC)


Initialisierung eines Peripheriebausteins

Der Ablauf einer Initialisierung einer Peripherie ist grundsätzlich immer derselbe. Bevor irgend ein Register der Peripherie configuriert werden kann muss der Clock der Peripherie aktiviert werden.

Wie aus der System Architecture des STM32 ersichtlich ist sind die Peripherie Bausteine auf zwei Peripherie Busse aufgeteilt: APB1 und APB2 oder sitzen am AHB.

 Siehe RM0008 Reference manual, Seite 41 und 42

Je nachdem an welchem Bus die Peripherie angeschlossen ist muss die Funktion RCC_APB1PeriphClockCmd(...), RCC_APB2PeriphClockCmd(...) oder RCC_AHBPeriphClockCmd(...) verwendet werden.

In diesem Intro wird der GPIO Port D aktiviert, alle Ports hängen am APB2.

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);

Zum herausfinden welche Peripherie an welchem Bus hängt, die Codedoku konsultieren (stm32f10x_stdperiph_lib_um.chm) oder den Code von APB2PeriphClockCmd (bzw. APB1PeriphClockCmd oder RCC_AHBPeriphClockCmd) in stm32f10x_rcc.c ansehen.

Tipp: Strg Taste drücken und zugleich mit der linken Mousetaste eine Funktion anklicken öffnet das File und den zugehörigen Code im Editor.


Startupcode und Linkerscript

Wird mit dem TrueStudio Projektwizard ein Projekt erstellt dann kopiert TrueStudio die notwendigen Files in das Projekt. Soll das Projekt für eine andere Controller Linie configuriert werden oder soll der Code in den RAM so sind die Files zu ersetzen.

  • Linkerscript:
 <Projet>\stm32_flash.ld 

In diesem Intro ist der Code so gelinkt dass er in den Flash des Controllers geladen wird

Weitere Linkerscripts sind zu finden in

 <TrueStudio Installationsverzeichnis>\scripts\ld

  • Startupcode:
 <Projet>\firmware\CMSIS\CM3\DeviceSupport\ST\STM32F10x\startup\TrueSTUDIO\startup_stm32f10x_cl.s
 

In diesem Intro ist der StartupCode für einen Conection Line Controller in verwendung.

Startupcodes für andere STM32 Controller Lines sind zu finden in

 <TrueStudio Installationsverzeichnis>\Library\STM32F10x_StdPeriph_Lib_V3.3.0\Libraries\CMSIS\CM3\DeviceSupport\ST\STM32F10x\startup\TrueSTUDIO


Wo gibt es weitere Beispiele

Die STM32 Std. Periph. Library enthält viele Beispiele, da ist für jeden Peripheriebaustein was mit dabei.

TrueStudio hat die komplette Library bei der Installation mit auf die Platte kopiert. Diese ist zu finden in

 <TrueStudio Installationsverzeichnis>\Library\STM32F10x_StdPeriph_Lib_V3.3.0

Die Beispiele finde sich in

 ..\Library\STM32F10x_StdPeriph_Lib_V3.3.0\Project\STM32F10x_StdPeriph_Examples

Um das Beispiel zu testen wie in diesem Intro ein Projekt, dann den Code aus dem Beispiel in den Ordner src des Projektes kopieren. Die Ports anpassen, dann kann das Beispiel compiliert und getestet werden.


Verwandte Themen