Teil 3: Ein Chip, sie zu knechten

Microcontroller für das IoT: So programmieren Sie den STM32

Tam Hanna

© Shutterstock / Sentavio

Großbritannien mag in der klassischen Schwerindustrie keine große Rolle mehr spielen. Ein ebenda entwickelter Mikroprozessor trat indes die Weltherrschaft an. Im dritten Teil der Serie über Microcontroller für das IoT wenden wir uns der STM32-Familie zu.

X

Serie: Microcontroller für das Internet der Dinge

 Ein Chip, sie zu knechten: STM32

Mittlerweile sind ARM-MCUs so stromsparend, dass sie auch in klassisches Achtbitterterrain vordringen können. ARM unterstützt diesen Trend durch das Anbieten einer immer größer werdenden Anzahl verschiedener Cores (Abb. 1). Im Bereich Handcomputer entfällt der Gutteil der Stückzahlen auf die Cortex-A-Architektur, die auf die Ansprüche von Android und Co. optimiert sind. Die Cortex-M-Familie weist einen vom Umfang her reduzierten Kern auf, der für den Einsatz als klassischer Microcontroller vorgesehen ist. Von Android-Devices benötigte Komponenten fallen bei diesen MCUs unter den Tisch, um die für Kosten und Energieverbrauch relevante Transistorzahl zu senken.

STMicroelectronics hat sich im Laufe der letzten Jahre signifikante Marktanteile erarbeitet: Prozessoren des Unternehmens finden sich in diversen Prozessrechnern. Dies liegt unter anderem daran, dass die Firma vergleichsweise preiswerte Evaluationsboards anbietet, die beim Hantieren mit den elektronisch anspruchsvollen ARM-CPUs hilfreich sind.

Wir wollen in den folgenden Abschnitten auf ein Evaluationsboard vom Typ STM32F429-Discovery setzen, das mit dem gleichnamigen Prozessor und einem kleinen resistiven Touchscreen ausgestattet ist. Die maximal 30 Euro teure Planare ist sehr leicht erhältlich. Neben diversen Versandhändlern findet man sie auch beim gut sortierten Elektronikdistributor.

Bei der Nutzung von ST-Evaluationskits sollten Sie zwei Grundregeln beachten. Erstens ist die Nutzung in kommerziellen Produkten verboten: Die Planare darf auf keinen Fall als „Prozessrechner“ verbaut werden. Zweitens gibt es für „Kleinkunden“ keinen nennenswerten Support: Wer nicht einige tausend IS pro Jahr kauft, darf sich mit drittklassiger Dokumentation und einem primär von Endkunden gepflegtem Forum herumschlagen.

Alles in GCC

Auch wenn GCC unter Embedded-Experten nicht unbedingt den besten Ruf genießt, wollen wir unsere Experimente in diesem Artikel trotzdem mit dem quelloffenen Compileroldie durchführen. Da wir in den letzten beiden Teilen dieser Serie unter Linux gearbeitet haben, kommt diesmal eine auf Windows XP basierende Workstation zum Einsatz. Die 64-Bit-Version des Betriebssystems wird von Seiten der Entwickler explizit nicht unterstützt. Unter anderen Betriebssystemen lässt sich der Workflow ohne großen Aufwand nachvollziehen. Weitere Informationen hierzu gibt es hier.

Besuchen Sie die GCC-ARM-Embedded-Seite mit einem Browser Ihrer Wahl, und laden Sie die Datei gcc-arm-none-eabi-4_9-2015q3-20150921-win32.exe über die auf der rechten Seite eingeblendeten grünen Buttons herunter und führen Sie sie aus. Da Windows ohne Build-Verwaltungswerkzeug auskommen muss, folgen im nächsten Schritt der Download und die Installation der unter folgender Adresse bereitstehenden Datei gnuarmeclipse-build-tools-win32-2.6-201507152002-setup.exe.

Starten Sie die IDE danach. Von Seiten des Projektteams wird das Herunterladen einer „frischen“ Version der Eclipse IDE for C/C++ Developers empfohlen, die einen eigenen Workspace bekommt. Unter diesem Link findet sich ein Repository, in dem die Plug-ins bereitstehen – laden Sie sie wie gewohnt herunter.

Die eigentliche Prozessorkonfiguration wird in der Packs-Ansicht verwaltet, die sich durch Anklicken des braunen Paketsymbols in der Toolbar öffnet. Nach der Installation des Plug-ins ist ein Klick auf das Refresh-Symbol notwendig: Er weist die IDE dazu an, die heruntergeladenen Konfigurationen zu analysieren. Im Boardsfenster auf der linken Seite des Bildschirms lässt sich Eclipse danach auf die Kategorie STMicroelectronics->STM32F429I-Disvobery beschränken; klicken Sie das von Keil angebotene Paket rechts an, und wählen Sie die Option Install aus. Die IDE installiert die aktuellste Version des Pakets daraufhin in den Packages-Unterordner des Benutzerprofils.

Der für die Kommunikation zwischen PC und Planare notwendige Treiber steht hier bereit. Extrahieren Sie das Archiv, und führen Sie den darin enthaltenen Installationsassistenten aus. Unter dieser Adresse findet sich die für die Kommunikation zwischen Planare und Debugger notwendige OpenOCD-Erweiterung.

Schließen Sie den Prozessrechner nach dem obligatorischen Reboot und dem Stecken der in Abbildung 2 gezeigten Jumper an den Rechner an – das Blinken der roten COM-LED weist auf Datenkommunikation hin, während die Station den Assistenten zur Hardwareerkennung anwirft.

Abb. 2: Bei gezogenem Jumper ist der Prozessor der Planare für den Debugger nicht ansprechbar

Ein erster Test

Massimo Banzi folgte mit dem Arduino Zero einen bei anderen Herstellern schon lange etablierten Trend: Preiswerte Evaluationsboards werden normalerweise in „Personalunion“ mit einer mehr oder weniger stark abgespeckten Version des Kommandogeräts ausgeliefert. In unserem Fall hört der Debugger auf das ST-LINK-Protokoll, das unter Unix ärgerlicherweise nur teilweise unterstützt wird. Zur – hier nicht näher besprochenen – Arbeit mit JTAG ist eine Adaption der Planare notwendig, die unter diesem Link beschrieben ist.

Erstellen Sie im nächsten Schritt ein neues C++-Projekt. Der Generationsassistent bietet in der Rubrik Executables eine Gruppe von Vorlagen an, die die verschiedenen Prozessoren abbilden. Da unsere Planare einen STM32F429 mitbringt, wählen wir die Rubrik FTM32F4xx C/C++ Project. Als Compiler dient Cross ARM GCC. Nach einem Klick auf Next fragt Eclipse, wie in Abbildung 3 gezeigt, nach weiteren Informationen zur Hardware.

Abb. 3: Embedded-Programmierung setzt Wissen über den inneren Aufbau der Planare voraus

Im Fall unserer Planare lautet der Prozessortyp STM32F429xx. Der im Feld External Clock befindliche Wert beschreibt die Geschwindigkeit des Schwingkreises und kann unverändert übernommen werden. Wichtig ist, dass der Flashspeicher eine Kapazität von 2 048 KB aufweist. Weitere Einstellungen sind erst im Fenster Cross GNU ARM Toolchain notwendig, wo im Feld Toolchain path der Wert „C:\Programme\GNU Tools ARM Embedded\4.9 2015q3“ eingegeben wird.

Nach dem Erstellen eines neuen ARM-Projekts wirft Eclipse rund vierzig Fehler. Der Gutteil davon entsteht durch das Fehlen von Indexinformationen, die im Laufe von fünf bis zehn Minuten im Hintergrund entstehen. Wenn die Fehlerliste keine Meldungen enthält, die auf das Nicht-Finden-Können von Programmen hinweisen, ordnen Sie einfach einen weiteren Rebuild an. Am Ende bleiben normalerweise die acht in der Abbildung 4 gezeigten Fehler „stehen“.

Abb. 4: Manchmal wird auch richtiger Code beanstandet

Es handelt sich dabei witzigerweise um keine echten Compilerfehler. Vielmehr probt das in neuen Versionen des CDT enthaltene Codan-Werkzeug den Aufstand und blockiert den Compiler wegen imaginärer Bugs. Wechseln Sie deshalb in die Rubrik Window | Preferences | C/C++ | Code Analysis, und deaktivieren Sie alle Prüfungen. Klicken Sie das Projekt im Project Explorer danach rechts an, um die Eigenschaftsseite zu öffnen. Unter C/C++ Build | Settings | Devices wird das passende Board ausgewählt und mit einem Klick auf Apply aktiviert. Bei dieser Gelegenheit wird unter Run/Debug | String Substitution | openocd_path der Wert „C:\Programme\GNU ARM Eclipse\OpenOCD\0.9.0-201505190955\bin“ eingepflegt.

Im nächsten Schritt wird eine neue Debuggerkonfiguration vom Typ GDB OpenOCD Debug angelegt. In der Registerkarte Debugger wird im Feld Config Options der String „-f board\stm32f429discovery.cfg“ eingegeben. Die Datei stm32f429discovery.cfg ist ein im Unterverzeichnis /boards liegendes Konfigurationsfile, das OpenOCD an die vorliegende Planare anpasst. Nach einem Klick auf Debug startet der Prozessrechner die neue Software – das von STM bereitgestellte Displayprogramm geht dabei über den Jordan, was sich in seltsamen Displayausgaben äußert.

Für uns ist die Funktion main besonders interessant, da sie für die Ausgabe der in der Debuggerkonsole aufscheinenden Meldungen zuständig sind:

  

int

main(int argc, char* argv[])

 {

   trace_puts("Hello ARM World!");

   trace_printf("System clock: %u Hz\n", SystemCoreClock);

trace_puts und trace_printf unterscheiden sich insofern, als zweitere Methode die Ausgabe weiterer Parameter bewerkstelligt. Breakpoints lassen sich wie gewohnt platzieren – achten Sie darauf, dass die IDE von Haus aus einen Breakpoint in das erste Statement von main() setzt.

HALli Galli!

ARM-MCUs unterscheiden sich von klassischen Controllern durch ihre wesentlich höhere Komplexität. Am AVR oder am MSP430 mit einer Zeile zu bewerkstelligende Aufgaben setzen auf diesem Prozessor Dutzende von Zeilen voraus. Compilerhersteller begegnen diesem Problem durch das Anbieten von Programmierschnittstellen, die prozessorspezifische Direktiven zu abstrahieren suchen.

Im Fall des von Eclipse generierten Codebeispiels wird diese nur teilweise genutzt: BlinkLed.cpp ruft HAL_GPIO_Init auf, um Port-Pins zu initialisieren. Das Lesen und Schreiben erfolgt durch handgeschriebene Registerzugriffe: Die in stm32f4xx_hal_gpio.c bereitgestellten Lesemethoden werden nicht verwendet. Im Unterordner <workspace>\SUSSTM1\system\include\stm32f4-hal finden sich weitere Dateien, die die diversen Module des Prozessrechners exponieren.

Das Blinken von LEDs ist auf Acht- und Sechzehnbittern mit einer oder zwei Codezeilen erledigt. Unser STM32F429 erweist sich als wesentlich komplizierter: Sein GPIO-Subsystem weist jedem Port ein gutes Dutzend Register zu. Beginnen wir unsere Betrachtungen mit den folgenden beiden Funktionen, die aus BlinkLED.cpp entnommen sind (Listing 1).

  

void

BlinkLed::toggle ()

 {

   if (BLINK_GPIOx(fPortNumber)->IDR & fBitMask)

     {

       BLINK_GPIOx(fPortNumber)->ODR &= ~fBitMask;

     }

   else

 {

    BLINK_GPIOx(fPortNumber)->ODR |= fBitMask;

   }

 }

 void

 BlinkLed::turnOn ()

 {

    if (fIsActiveLow)

    {

      BLINK_GPIOx(fPortNumber)->BSRR = BLINK_PIN_MASK(fBitNumber + 16);

    }

    else

    {

      BLINK_GPIOx(fPortNumber)->BSRR = fBitMask;

    }

  }

toggle() nutzt die Lese- und Schreibregister IDR und ODR zur direkten Interaktion mit den Portpins. Die Inhalte des jeweiligen Registers wandern direkt in Richtung der GPIO-Pins. turnOn() kommt ohne Sentinenz aus. STMs IO-Core ist insofern einzigartig, als er mit dem 32 Bit breiten und nur schreibbaren BSRR das direkte Adressieren einzelner Pins erlaubt (Abb. 5).

 

Abb. 5: Das BSRR-Register nutzt die volle Wortbreite des Prozessors

Bei einem Schreibvorgang in BSRR beginnt die CPU mit einer Analyse der angelieferten Daten. Ist das einem bestimmten Pin zugeordnete BS-Bit high, so wird der Pin aktiviert. Das Setzen des BR-Bits sorgt stattdessen dafür, dass das System den Pin abschaltet. Dieser auf den ersten Blick komplex erscheinende Vorgang erweist sich in der Praxis als sinnvoll, weil die Applikation einzelne Pins „direkt“, also ohne vorheriges Auslesen der im Register befindlichen Werte, ansprechen kann.

Der am Heritage College zu Kanada arbeitende Hussam Al-Hertani bietet unter dieser URL eine Beschreibung der Register an, die dem Datenblatt in Sachen Lesbarkeit überlegen ist. Wer den absoluten Informationsoverload begehrt, wird hier sowie hier bestens bedient.

Mach’ den Würfel

STM32 bietet mit „HAL“ – der Name ist eigentlich irreführend, weil klassische HALs eine andere Rolle spielen – ein grundlegendes Headerpaket an. Für fortgeschrittene Aufgaben offeriert das Chiphaus mit STM32CubeF4 eine reichhaltigere Programmierumgebung, die sich zudem als eine Art Hardwareabstraktionsschicht sieht (Abb. 6).

Öffnen Sie im ersten Schritt die Seite http://www.st.com/web/en/catalog/tools/PF259243 in einem Browser Ihrer Wahl, und scrollen Sie ganz nach unten. Der Downloadbefehl findet sich – warum auch immer – in der Rubrik Sample&Buy und liefert ein rund 300 MB großes Archiv an. In der Literatur finden sich immer wieder Verweise auf ein als STM32CubeMX bezeichnetes Werkzeug, das bei der Konfiguration und Auswahl von STM-Mikroprozessoren hilft. Das in diesem Artikel nicht erforderliche Tool ist nicht Teil der Cube-Distribution und muss bei Bedarf hier heruntergeladen werden.

Extrahieren Sie die Datei in einen angenehm erreichbaren Ordner, und erstellen Sie ein neues Projekt in Eclipse. Erzeugen Sie im Verzeichnis /system/include einen Unterordner namens BSP/Components, und versehen Sie ihn mit den unter STM32Cube_FW_F4_V1.9.0\Drivers\BSP\Components befindlichen Hardwaretreibern. Im nächsten Schritt wandern die in STM32Cube_FW_F4_V1.9.0\Drivers\BSP\STM32F429I-Discovery liegenden .c-Dateien in das /src-Verzeichnis des Projekts. Die ebenda befindlichen Header müssen in ein beliebiges Unterverzeichnis von /BSP kopiert werden. STM32Cube_FW_F4_V1.9.0\Utilities\Fonts enthält eine Gruppe von Bitmap-Fonts, die in /src/fonts wandern. Die Headerdatei kommt der Einfachheit halber nach /include.

An dieser Stelle ist etwas Handarbeit erforderlich: In den .c-Dateien der HAL für die Planare finden sich Include-Pfade, die mit der vorliegenden Projektstruktur inkompatibel sind. Dieses Problem lässt sich durch Adaption nach folgendem Schema lösen:

// Alt

#include "stm32f429i_discovery_lcd.h"

// Neu

#include "BSP/STMDisco/stm32f429i_discovery_lcd.h"

Die Datei stm32f429i_discovery_lcd.c inkludiert eine Gruppe von .c-Dateien. Entfernen Sie den im Snippet gezeigten Block ersatzlos – die Fontdateien werden im Rahmen der Kompilation sowieso eingebunden; eine zweifache Inklusion führt zu Linkerfehlern:

#include "fonts/font24.c"

#include "fonts/font20.c"

#include "fonts/font16.c"

#include "fonts/font12.c"

#include "fonts/font8.c"

Nach dem Anpassen aller Pfade sollte die Kompilation erfolgreich durchlaufen. Im Moment ist das Beispielprogramm nach wie vor „nur“ ein Blinker – schicken Sie es auf den Prozessrechner, um sich von der ordnungsgemäßen Funktion zu überzeugen.

Funktionsgenerator für Dummies

Böse Zungen behaupten, dass der Sprung vom semiprofessionellen zum professionellen Labor in der Anschaffung eines Funktionsgenerators besteht. Es handelt sich dabei um ein Gerät, das als Funktionen bezeichnete Spannungskurven ausgibt und so das Testen von Sendern und anderen Schaltkreisen erleichtert.

In der grauen Vorzeit wurden Funktionsgeneratoren „diskret“ realisiert: Komplexe analoge Schaltungen wurden zum Schwingen animiert, um so das gewünschte Verhalten zu erreichen. Dank immenser Fortschritte im Bereich der Digital-Analog-Konverter ist es heute möglich, auf das Konzept der DDS zu setzen. Es handelt sich dabei um Funktionsgeneratoren, die die gewünschte Funktion durch rapides Ausgeben von „Wellenpaketen“ erreichen.

Unser STM32F429 bietet sich ob seines fix verbauten DAC-Konverters für diese Aufgabe an. Dazu ist die in Listing 2 gezeigte Version von main() notwendig.

int

main(int argc, char* argv[])

{

  trace_puts("Hello ARM World!");

  trace_printf("System clock: %u Hz\n", SystemCoreClock);

  HAL_Init();

  SystemClock_Config();

  __GPIOA_CLK_ENABLE();
 
  __DAC_CLK_ENABLE();

  Timer timer;

  timer.start ();

ARM-MCUs zeichnen sich durch ihre aufwändige Clock-Gating-Logik aus: Nicht benötigte Peripheriegeräte können zwecks Energiesparen vom Systemtakt abgekoppelt werden. Die erste Aufgabe unseres Programms besteht darin, GPIO-Pins und DAC durch Aufruf der betreffenden Methoden mit Taktsignalen zu versorgen.

Im nächsten Schritt müssen die GPIO-Pins in analoge Ausgänge umgewandelt werden. Der DAC des STM32F429 ist fix mit den Pins PA4 und PA5 verbunden, das Deaktivieren der Pull-up-Widerstände verhindert Verfälschungen des ausgegebenen Signals:

 

GPIO_InitTypeDef GPIO_InitStruct;


GPIO_InitStruct.Pin   = GPIO_PIN_4 | GPIO_PIN_5;

GPIO_InitStruct.Mode  = GPIO_MODE_ANALOG;

GPIO_InitStruct.Pull  = GPIO_NOPULL;

HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

ST spendieren dem mit PA4 verbundenen Kanal des DA-Konverters einen Leistungstransistor, der sich durch Setzen von DAC_OUTPUTBUFFER_ENABLE in den Schaltkreis bringen lässt. DAC_TRIGGER_NONE weist den DAC dazu an, nach dem Einschreiben von neuen Werten per SetValue sofort mit der Konversion zu beginnen – der IS unterstützt auch Timer- und sogar DMA-getriebene Konversionen (Listing 3).

 

DacHandle.Instance = DAC;

if(HAL_DAC_Init(&DacHandle) != HAL_OK)

{

   trace_puts("Init Error!");

}

sConfig.DAC_Trigger = DAC_TRIGGER_NONE; // Act ASAP

sConfig.DAC_OutputBuffer = DAC_OUTPUTBUFFER_ENABLE; // Power up pwr transistor

if(HAL_DAC_ConfigChannel(&DacHandle, &sConfig, DACx_CHANNEL1) != HAL_OK)

{

   trace_puts("Config Error!");

}

Zu guter Letzt findet sich die eigentliche Ausgabe des Signals. DAC_Start muss nach dem ersten Einschreiben eines neuen Werts aufgerufen werden – nachfolgende Änderungen lassen sich durch SetValue bewerkstelligen (Listing 4).

HAL_DAC_SetValue(&DacHandle, DACx_CHANNEL1, DAC_ALIGN_12B_R, 0);

HAL_DAC_Start(&DacHandle, DACx_CHANNEL1);


while(1==1)

 {

  HAL_DAC_SetValue(&DacHandle, DACx_CHANNEL1, DAC_ALIGN_12B_R, 0);

  for(volatile int i=1;i<100;i++);

  HAL_DAC_SetValue(&DacHandle, DACx_CHANNEL1, DAC_ALIGN_12B_R, 868*1);

  for(volatile int i=1;i<100;i++);

  HAL_DAC_SetValue(&DacHandle, DACx_CHANNEL1, DAC_ALIGN_12B_R, 868*2);

  for(volatile int i=1;i<100;i++);

 }

}

SetValue nimmt die für den DAC vorgesehenen Parameter in drei Arten entgegen: Neben rechtsbündigen und linksbündigen zwölfbittigen Werten lässt sich der IS auch mit achtbittigen Werten füttern. Wir verwenden hier drei rechtsbündige zwölfbittige Werte, die eine Art „Treppenwellenform“ realisieren.

Die Kompilation des vorliegenden Programms scheitert wahrscheinlich mit einem Verweis auf fehlende Funktionsdeklarationen. Das liegt daran, dass das von den ARM-Tools erstellte Beispielprojekt Teile der HAL zwecks Geschwindigkeitssteigerung ausblendet. Öffnen Sie die Projekteigenschaften, und wechseln Sie in C/C++ General | Paths and Symbols | Source Location. Die Rubrik /SUSFuncGen/system ist mit einem Filterstring ausgestattet, der durch Anklicken von Edit Filter… bearbeitet werden kann. Markieren Sie die beiden DAC-Dateien, und klicken Sie auf Remove. Nach einem Rebuild des Projekts sollte alles ordnungsgemäß funktionieren. Abbildung 7 zeigt die resultierende Signalform.

Abb. 7: Ein Glättungskondensator und eine hochohmige Last würden das Überschießen reduzieren …

Im Namen des LCD

Das auf unserem STM32F429 verbaute Display liegt im Moment brach – Zeit, es ein wenig zu nerven. Aufgrund einer Besonderheit des Clock-Systems müssen wir die Reihenfolge der Initialisierungsmethoden nach folgendem Schema anpassen:

int

main(int argc, char* argv[])

 {

  . . .
 
  HAL_Init();

  __GPIOA_CLK_ENABLE();

  __DAC_CLK_ENABLE();

  SystemClock_Config();

Die eigentliche Initialisierung der Hardware erfolgt dann über die BSP_LCD-Methoden. Wir beschränken uns hier aus Platzgründen auf das Anzeigen eines blauen Bildschirms:

 

BSP_LCD_Init();

BSP_LCD_LayerDefaultInit(0, (uint32_t) LCD_FRAME_BUFFER);

BSP_LCD_SetLayerVisible(0, ENABLE);

BSP_LCD_SelectLayer(0);

BSP_LCD_Clear(LCD_COLOR_BLUE);

BSP_LCD_SetBackColor(LCD_COLOR_RED);

BSP_LCD_SetTextColor(LCD_COLOR_WHITE);

BSP_LCD_DisplayOn();

// HAL_Delay(500);

STMCube arbeitet mit mehreren Ebenen. Da Ihr Code in den gerade nicht am Bildschirm befindlichen Teil des Bildspeichers schreiben kann, wird das bei älteren Handcomputern oft sichtbare „Tearing“ vermieden. Wir weisen den Prozessrechner zur Nutzung der nullten Layer an und färben diese danach durch Aufruf von LCD_Clear blau. Die Zuweisung der Textfarben wäre für die Nutzung der Fonts hilfreich – BSP_LCD enthält eine Vielzahl von Convenience-Funktionen, die beim Zeichnen von Linien, Rechtecken, Kreisen und Texten helfen.

Der Zugriff auf das LCD setzt mehrere von Haus aus deaktivierte HAL-Komponenten voraus. Da die Kompilation der Gesamt-HAL auch auf älterer Hardware in realistischer Zeit erfolgt, empfiehlt es sich, den weiter oben erwähnten Filter zur Gänze zu löschen und das Projekt danach zu bereinigen und komplett neu zu kompilieren.

Die „diskrete“ Realisierung komplexer Benutzerschnittstellen per Framebuffer ist eine höchst unergiebige Aufgabe. STM arbeitet im Grafikbereich seit Jahren mit SEGGER Microcontroller zusammen: STemWin ist eine abgespeckte Version des GUI-Stacks des Unternehmens, die in Binärform für die Nutzer von ST-CPUs kostenlos zu haben ist. Leider gilt auch hier, dass eine detaillierte Besprechung des Produkts den Rahmen des Artikels sprengen würde – wir erwähnen das Produkt nur, um Ihnen unnötige Handarbeit zu ersparen.

Immer weiter, ohne Ende!

Unser Generator bietet an mehreren Stellen Erweiterungspotenzial. Das manuelle Generieren der Wellenformen und das Timing per for sind alles andere als kommod: Sinus und Co. nehmen viel Rechenleistung in Anspruch, die sich durch die Nutzung einer Tabelle einsparen ließe. Da die Arbeit mit Prozessrechnern immer eine interdisziplinäre Wissenschaft ist, gibt es auf Seiten der Hardware Optimierungspotenzial. Das direkte Anschließen von Verbrauchern an den DAC ist nicht nur aus „formeller Sicht“ unschön: Die Stromlieferfähigkeit der Bausteine unterliegt oft engen Grenzen. Wer seinen Funktionsgenerator im Labor einsetzen möchte, sollte dem Gerät zumindest einen Instrumentenverstärker spendieren. Zur Bekämpfung der Restwelligkeit böte sich die Nutzung eines Rekonstruktionsfilters an, der die konzeptbedingt vorhandenen Treppen mit seiner langsamen Reaktion „glattbügelt“.

Zu guter Letzt könnten Sie auch die Arbeitsgeschwindigkeit erhöhen. Die unter folgendem Link bereitgestellte Application Note enthält ein Prinzipschaltbild, das den Konverter zur Arbeit mit bis zu 5 MS/s befähigt.

Fazit

Ob der immensen Komplexität von ARM-Prozessoren ist es unmöglich, die CPU in einem Artikel komplett vorzustellen. Eine Architekturbeschreibung würde allein mehrere hundert Seiten in Anspruch nehmen. Erfreulicherweise muss man sich als Entwickler aber nicht unbedingt mit den Feinheiten der verschiedenen CPUs herumärgern. Der Markt ist voller Echtzeitbetriebssysteme, die komplexer Peripherie dank eigener Hardwareabstraktionsschichten den Schrecken nehmen. Im nächsten Teil dieser Serie werden wir unseren STM32 mit einem RTOS bekanntmachen.

Da Funktionsgeneratoren im Handel nach wie vor teuer sind, hofft der Autor auf rege Diskussion: Wer unseren rudimentären FUG um interessante Features erweitert und einen Leserbrief schreibt, findet sich vielleicht in der nächsten Ausgabe des Eclipse Magazins wieder. Bis dahin wünschen wir Ihnen: gut Code!

Geschrieben von
Tam Hanna
Tam Hanna
Tam Hanna befasst sich seit der Zeit des Palm IIIc mit der Programmierung und Anwendung von Handcomputern. Er entwickelt Programme für diverse Plattformen, betreibt Onlinenewsdienste zum Thema und steht unter tamhan@tamoggemon.com für Fragen, Trainings und Vorträge gern zur Verfügung.
Kommentare

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.