Einführung in die Programmierung von STM32 ARM Cortex-M 32-Bit-Mikrocontrollern

In diesem ausführlichen Artikel erfahren Sie, wie Sie eingebettete Firmware für STM32 Cortex-M 32-Bit-Mikrocontroller mit den verschiedenen Entwicklungstools entwickeln.

STM32 Mikrocontroller

77 Aktien

Die STM32 serie sind einige der beliebtesten mikrocontroller verwendet in eine breite vielzahl von produkten. Sie haben auch eine ausgezeichnete Support-Basis von mehreren Mikrocontroller-Entwicklungsforen.

Diese Familie von Mikrocontrollern von STMicroelectronics basiert auf dem 32-Bit-Prozessorkern ARM Cortex-M.

STM32-Mikrocontroller bieten eine große Anzahl von seriellen und parallelen Kommunikationsperipheriegeräten, die mit allen Arten von elektronischen Komponenten wie Sensoren, Displays, Kameras, Motoren usw. verbunden werden können. Alle STM32-Varianten sind mit internem Flash-Speicher und RAM ausgestattet.

Das Leistungsspektrum des STM32 ist recht umfangreich. Zu den grundlegendsten Varianten gehören die Unterserien STM32F0 und STM32F1, die mit einer Taktfrequenz von nur 24 MHz beginnen und in Gehäusen mit nur 16 Pins erhältlich sind.

Am anderen Leistungsextremum arbeitet der STM32H7 mit bis zu 400 MHz und ist in Gehäusen mit bis zu 240 Pins erhältlich.

Die fortgeschritteneren Modelle sind mit Gleitkommaeinheiten (FPU) für Anwendungen mit hohen Anforderungen an die numerische Verarbeitung erhältlich. Diese fortschrittlicheren Modelle verwischen die Grenze zwischen einem Mikrocontroller und einem Mikroprozessor.

Schließlich wurde die STM32L-Unterserie speziell für tragbare Anwendungen mit geringem Stromverbrauch entwickelt, die mit einer kleinen Batterie betrieben werden.

Entwicklungswerkzeuge

Entwicklungswerkzeuge werden benötigt, um den Code zu entwickeln, den Mikrocontroller zu programmieren und den Code zu testen/ debuggen. Die entwicklung werkzeuge umfassen:

  • Compiler
  • Debugger
  • In-Circuit Serial Programmer (ICSP)
Programmierung STM32

Programmierung die STM32 über die In-Circuit-Serial-Programmer (ICSP).

Für die Codeentwicklung auf STM32-Mikrocontrollern stehen verschiedene Softwareentwicklungstools zur Verfügung. Die Softwaretools sind als integrierte Entwicklungsumgebungen (IDE) verfügbar, die alle erforderlichen Tools in einer integrierten Umgebung kombinieren.

Zwei gängige Entwicklungspakete sind:

  • Keil MDK ARM (uVison5 IDE) – Die MDK ARM IDE ist eine sehr stabile Entwicklungsumgebung, die kostenlos heruntergeladen werden kann. Es ermöglicht die Entwicklung von Code bis zu einer Programmgröße von 32 KB. Für die Entwicklung größerer Programme muss hier eine lizenzierte Version erworben werden.
  • CoIDE – Eine kostenlose Toolkette, die auf einer abgespeckten Version der Eclipse-IDE basiert, die zusammen mit einer eingebetteten ARM-Version des kostenlosen GCC-Compilers integriert ist.

Es gibt auch mehrere andere IDEs, die für die Verwendung mit STM32-Mikrocontrollern verfügbar sind. Dieser Artikel konzentriert sich jedoch auf die Entwicklung und das Flashen eines Programms mit der sehr beliebten Keil MDK ARM uVision5 IDE.

Abgesehen von den Softwaretools ist ein In-Circuit Serial Programmer (ICSP) erforderlich, um den Code auf dem eigentlichen Mikrocontroller zu programmieren und zu testen. Der ICSP wird benötigt, um den Mikrocontroller über einen USB-Anschluss mit den PC-Softwaretools zu verbinden.

Die ARM Cortex-M Mikrocontroller unterstützen zwei Programmierprotokolle: JTAG (benannt von der Electronics Industry Association Joint Test Action Group) und Serial Wire Debug (SWD).

Es gibt mehrere ICSP-Programmierer, die diese Protokolle unterstützen, darunter:

  • Keil U-Link 2
  • Segger J-Link
  • ST-Link

Entwicklung der ersten Anwendung

Es ist immer am einfachsten, mit einem leicht verfügbaren Basiscode-Framework zu beginnen. Fügen Sie dann den Code hinzu, der für die spezifische Anwendung und das Modell des Mikrocontrollers erforderlich ist.Glücklicherweise bietet STMicroelectronics ein sehr nützliches grafisches Tool namens STM32CubeMX, das bei der Erstellung eines Basisanwendungsprojekts für jeden STM32-Mikrocontroller Ihrer Wahl hilft. Es kann auch verwendet werden, um die Peripheriegeräte auf den Multiplex-Pins des Mikrocontrollers zu konfigurieren.

Das STM32CubeMX-Tool kann hier heruntergeladen werden. Der STM32Cube wird mit einem umfangreichen Satz von Treibern für alle Arten von Peripheriegeräten und Unterstützung für ein optionales FreeRTOS (ein kostenloses Echtzeit-Betriebssystem) geliefert, das in den Code vorintegriert ist.

Im folgenden Abschnitt wird detailliert beschrieben, wie Sie eine einfache UART-Anwendung für den STM32F030-Mikrocontroller erstellen, die alles wiedergibt, was in einem Terminalfenster eingegeben wird.

  • Installieren Sie die STM32CubeMX-Software.
  • Führen Sie die Anwendung aus und wählen Sie Neues Projekt. Anschließend wird das MCU-Auswahlfenster wie unten gezeigt geöffnet.
  • Doppelklicken Sie, um das verwendete Mikrocontrollermodell auszuwählen. In diesem Fall verwenden wir den STM32F030K6. Anschließend gelangen Sie zur Pinbelegungsseite für den ausgewählten Mikrocontroller.

Screenshot zum Einrichten eines neuen Projekts in STM32CubeMX

Der STM32F030K6 ist ein ARM Cortex-M0-Kern mit 32 KB Flash-Speicher und 4 KB RAM-Speicher. Der Beispielcode aktiviert den UART, der die Pins PA9 und PA10 zum Empfangen und Senden serieller Daten verwendet, wie unten mit den grünen Pins gezeigt.

Screenshot, der die Pinbelegung für STM32F030K6 in STM32CubeMX zeigt

Konfigurieren Sie die UART-Einstellungen auf der Registerkarte Konfiguration und wählen Sie die UART-Einstellungen wie unten gezeigt. Aktivieren Sie die Option NVIC Global Interrupt auf der Registerkarte NVIC-Einstellungen.

Screenshot zur Konfiguration der UART–Einstellungen STM32CubeMX

Navigieren Sie anschließend zu Project->Settings, um den neuen Projektnamen hinzuzufügen und die zu verwendende Tool Chain IDE auszuwählen. Setzen Sie in diesem Beispiel den Projektnamen auf ‚UARTEcho‘ und wählen Sie die Keil-MDK5-IDE für die Projektentwicklung aus.

Generieren Sie schließlich den Projektcode, indem Sie auf Project -> Generate Code klicken.

Code erstellen und flashen

Öffnen Sie nun die generierte MDK-ARM-Projektdatei UARTEcho\MDK-ARM\UartEcho.uprojx.

Dieses Programm initialisiert bisher nur das UART-Peripheriegerät und stoppt in einer Endlosschleife.

Es ist wichtig zu beachten, dass der STM32Cube /* USER CODE BEGIN x */ und /* USER CODE END x */ Kommentarblöcke generiert, um den benutzerspezifischen Code zu implementieren. Der Benutzercode muss innerhalb dieser Kommentarblöcke geschrieben werden. Immer wenn der Code mit geänderten Konfigurationen neu generiert wird, behält das STMCube-Tool den Benutzercode innerhalb dieser Benutzerkommentarblöcke bei.

Definieren Sie als Nächstes eine globale Variable, um ein Byte vom UART im main zu empfangen.c quelle datei:

/* USER CODE BEGIN PV *//* Private variables ———————————————————*/static uint8_t recv_data;/* USER CODE END PV */

Nach alle der initialisierung code, ermöglichen die fahrer zu erhalten 1 byte. Die folgende Funktion aktiviert das Interruptbit RXNE.

/* USER CODE BEGIN 2 */HAL_UART_Receive_IT(&huart1, &recv_data, 1);/* USER CODE END 2 */

Fügen Sie nun eine Callback-Funktion hinzu, um den Empfangs-Interrupt zu verarbeiten und das empfangene Byte zu übertragen.

/* USER CODE BEGIN 0 */void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart){HAL_UART_Transmit(huart, huart->pRxBuffPtr, 1, 1000);}/* USER CODE END 0 */

Schließlich müssen wir den Code kompilieren und auf den Mikrocontroller flashen (herunterladen).

Wenn die Keil MDK ARM IDE installiert ist, stehen Treiber für ST-LINK V2, J-Link und Ulink2 zur Verfügung. Der ST-Link Debugger wird standardmäßig ausgewählt. Gehen Sie zu Projects->Options for Target und wählen Sie auf der Registerkarte Debug den verwendeten ICSP-Programmierer aus.

Flashen Sie den Code, indem Sie Flash->Download auswählen.

HINWEIS: Laden Sie unbedingt Ihren kostenlosen PDF-Leitfaden 15 Schritte zur Entwicklung Ihres neuen elektronischen Hardwareprodukts herunter.

Der Mikrocontroller gibt nun alle über den UART empfangenen Daten wieder. Es kann mit einem USB-Seriell-Konverter an einen PC angeschlossen werden. Öffnen Sie am PC den COM-Port mit einer Terminalanwendung unter Verwendung der Einstellungen von 115200-8-N-1. Jetzt wird alles, was vom Terminal gesendet wird, durch den Mikrocontroller zurückgesendet.

Interrupt system

Die STM32 unterbrechen system ist basierend auf die ARM Cortex M core NVIC peripheren. Die STM32-MCUs unterstützen neben den 16 Interrupt-Kanälen des ARM-Kerns mehrere maskierbare Interrupt-Kanäle.

Die MCU-Serie STM32F0 unterstützt beispielsweise 32 maskierbare Interrupts. Die Ausnahme und die Interrupt-Vektor-Tabelle für diese Familie von MCUs ist in der folgenden Tabelle angegeben.

Interrupt Description Vector Address
Reserved 0x00000000
Reset Reset 0x00000004
NMI Non maskable interrupt. The RCC clock security system (CSS) is linked to the NMI vector 0x00000008
HardFault All class of faults 0x0000000C
SVCall System service call via SWI Instruction 0x0000002C
PendSV Pendable request for system service 0x00000038
SysTick System tick timer 0x0000003C
WWDG Window watchdog interrupt 0x00000040
PVD_VDDIO2 PVD and VDDIO2 supply comparator interrupt (combined with EXTI lines 16 and 31) 0x00000044
RTC RTC interrupts (combined EXTI lines 17, 19 and 20) 0x00000048
Flash Flash global interrupt 0x0000004C
RCC_CRS RCC and CRS global interrupts 0x00000050
EXTI0_1 EXTI line interrupts 0x00000054
EXTI2_3 EXTI line interrupts 0x00000058
EXTI4_15 EXTI line interrupts 0x0000005C
TSC Touch sensing interrupt 0x00000060
DMA_CH1 DMA channel 1 interrupt 0x00000064
DMA_CH2_3
DMA2_CH1_2
DMA channels 2 and 3 interrupts
DMA2 channel1 and 2 interrupts
0x00000068
DMA_CH4_5_6_7
DMA2_CH3_4_5
DMA channel 4,5,6 and 7 interrupts
DMA2 channel 3, 4, and 5 interrupts
0x0000006C
ADC_COMP ADC and COMP interrupts (Combined EXTI lines 21 and 22) 0x00000070
TIM1_BRK_UP_TRG_COM TIM1 break, update, trigger and commutation interrupts 0x00000074
TIM1_CC TIM1 capture compare interrupt 0x00000078
TIM2 TIM2 global interrupt 0x0000007C
TIM3 TIM3 global interrupt 0x00000080
TIM6_DAC TIM6 global interrupt and DAC underrun interrupt 0x00000084
TIM7 TIM7 global interrupt 0x00000088
TIM14 TIM14 global interrupt 0x0000008C
TIM15 TIM15 global interrupt 0x00000090
TIM16 TIM16 global interrupt 0x00000094
TIM17 TIM17 global interrupt 0x00000098
I2C1 I2C1 global interrupt (combined with EXTI line 23) 0x0000009C
I2C2 I2C2 global interrupt 0x000000A0
SPI1 SPI1 global interrupt 0x000000A4
SPI2 SPI2 global interrupt 0x000000A8
USART1 USART1 global interrupt (combined with EXTI line 25) 0x000000AC
UART2 USART2 global interrupt (combined with EXTI line 26) 0x000000B0
USART3_4_5_6_7_ 8 USART3, USART4, USART5, USART6, USART7, USART8 global interrupts (combined with EXTI line 28) 0x000000B4
CEC_CAN CEC and CAN global interrupts (combined with EXTI line 27 0x000000B8
USB USB global interrupt (combined with EXTI line 18) 0x000000BC

Extended Interrupts and Events Controller (EXTI)

Die STM32-MCUs verfügen über einen erweiterten Interrupts and Events Controller, der die externen und internen asynchronen Ereignisse / Interrupts verwaltet und die Ereignisanforderung an den CPU / Interrupt-Controller und eine Weckanforderung an den Power Manager generiert.

Jede der ein oder mehreren EXTI-Leitungen wird einem der NVIC-Interruptvektoren zugeordnet.

Für die externen Interruptleitungen sollte die Interruptleitung konfiguriert und aktiviert werden, um einen Interrupt zu erzeugen. Dies geschieht, indem die beiden Triggerregister mit der gewünschten Flankendetektion programmiert werden und die Interruptanforderung durch Schreiben einer ‚1‘ in das entsprechende Bit im Interruptmaskenregister freigegeben wird.

Externer Interrupt und GPIO-Mapping

Jeder der auf dem System verfügbaren GPIOs kann so konfiguriert werden, dass er einen Interrupt generiert. Jede der EXTI-Interrupt-Leitungen ist jedoch mehreren GPIO-Pins zugeordnet. Zum Beispiel PIO0 auf allen verfügbaren GPIO-Ports (A, B, C usw.) wird der Zeile EXTI0 zugeordnet. PIO1 für alle Ports wird der EXTI1-Leitung usw. zugeordnet.

Einige der EXTI-Linien werden zu einem einzigen NVIC-Vektor kombiniert. Beispielsweise wird EXTI4_15 einer einzelnen Vektoradresse zugeordnet, sodass für alle Interrupts von PIO4 bis PIO15 eine einzige Interruptroutine vorhanden ist. Die Quelle des Interrupts kann jedoch durch Lesen des ausstehenden Interruptregisters identifiziert werden.

Eine wichtige Sache, die beim Entwerfen eines Systems mit den STM32-MCUs zu beachten ist, ist die Auswahl der GPIO-Pins für die Interrupts. Die MCU verfügt möglicherweise über mehr als 16 GPIOs auf dem Gerät, es sind jedoch nur 16 externe Interruptleitungen verfügbar.

Zum Beispiel kann EXTI_0 entweder PA0 oder PB0 zugeordnet werden, aber nicht beiden. Bei der Auswahl der Pins für externe Interrupts sollten sie daher so gewählt werden, dass sie eindeutig einer der EXTI-Leitungen zugeordnet werden können.

Im folgenden Abschnitt wird beschrieben, wie ein Interrupt mit dem STM32-Cube konfiguriert wird.

screenshot Konfigurieren des Interrupts STM32CubeMX

Wählen Sie die Registerkarte Konfiguration und wählen Sie das Hardwaremodul aus, für das der Interrupt konfiguriert werden soll. Das Fenster Modulkonfiguration wird geöffnet.

Wählen Sie dann die Registerkarte NVIC-Einstellungen und aktivieren Sie den globalen Interrupt.

Der Code zum Aktivieren des Interrupts für das Modul wird im stm32f0xx_hal_msp generiert.c in der HAL_<Modul>_MSPInit(…) Funktion.

/* USART1 interrupt Init */HAL_NVIC_SetPriority(USART1_IRQn, 0, 0);HAL_NVIC_EnableIRQ(USART1_IRQn);

Der vom STM32-Cube generierte Code enthält die IRQ_Handler-Implementierung aller Interrupts. Wenn der Interrupt aktiviert ist, wird der Code in die Anwendung aufgenommen.

Normalerweise verarbeitet der generierte Code bereits den IRQ und löscht das Flag, das den Interrupt generiert hat. Anschließend wird ein Anwendungsrückruf aufgerufen, der dem Ereignis entspricht, das den Interrupt für das Modul generiert hat.

Die STM32 HAL (Hardware Abstraction Layer) implementiert einen Callback für jeden der Ereignistypen innerhalb jedes Moduls als Teil des Treibers. In diesem Beispiel sollte der Rx Transfer Complete Callback aus dem stm32f0xx_hal_UART kopiert werden.c-Datei.

Die Callback-Funktionen innerhalb des Treibers werden mit einem __weak linker Attribut implementiert. Der Benutzer muss eine Kopie der erforderlichen Rückruffunktion implementieren, indem er das Attribut __weak in einer der Anwendungsdateien entfernt und dann die spezifische Behandlung schreibt, die in dieser Funktion erforderlich ist.

/*** @brief Rx Transfer completed callback.* @param huart UART handle.* @retval None*/__weak void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart){/* Prevent unused argument(s) compilation warning */UNUSED(huart);

/* NOTE : This function should not be modified, when the callback is needed,the HAL_UART_RxCpltCallback can be implemented in the user file.*/}

Fazit

Dieses Tutorial ist eine Einführung in das Schreiben einer Anwendung, die mit der STM32-Familie von Mikrocontrollern arbeitet. Es gibt mehrere andere Methoden zum Schreiben einer Anwendung, aber die STM32Cube-Anwendung ist eine einfache und intuitive Methode, um loszulegen.

Dieses Tool vereinfacht die Initialisierung der Mikrocontroller-Peripherie. Es verbessert auch die Wartbarkeit des Codes, insbesondere wenn es Hardware-Revisionen gibt, die eine Neuzuordnung der Signale auf verschiedene Pins erfordern.

Ein weiterer Vorteil der Verwendung des STM32Cube-Tools besteht darin, dass es einen Bericht über die Benutzerkonfiguration für den Mikrocontroller generiert. In diesem Bericht werden der Uhrenbaum, die Pin-Zuordnung und die Hardwaremodulkonfiguration beschrieben, die alle sehr nützlich sind.

Es gibt auch einige andere Codebibliotheken und Beispielprogramme für alle STM32-Varianten. Unterstützung für mehrere IDEs ist ebenfalls enthalten.

Wenn Ihr Projekt einen ausgeklügelten 32-Bit-Mikrocontroller erfordert, empfehle ich die STM32-Serie. Sie sind nicht nur leistungsstark und beliebt, sondern STM32-Mikrocontroller sind auch recht erschwinglich.

Benötigen Sie weitere Schulungen zur Programmierung von STM32-Mikrocontrollern? Wenn ja, hier ist ein ausführlicherer Einführungskurs, den Sie sich ansehen sollten.

Dieser Artikel wurde von Mohan Kashivasi von Vithamas Technologies geschrieben. Er ist auch einer der Experten, die Ihnen innerhalb der Hardware Academy mit Ihrem Produkt zur Verfügung stehen.

Vergessen Sie nicht, Ihre kostenlose PDF-Datei herunterzuladen: Ultimativer Leitfaden für die Entwicklung und den Verkauf Ihres neuen elektronischen Hardwareprodukts. Sie erhalten auch meinen wöchentlichen Newsletter, in dem ich Premium-Inhalte teile, die in meinem Blog nicht verfügbar sind.

Andere Inhalte, die Ihnen gefallen könnten:

  • Einführung in den STM32CubeIDE für STM32-Mikrocontroller
  • So wählen Sie den Mikrocontroller für Ihr neues Produkt aus
  • Verwenden von Arduino als eingebettete Entwicklungsplattform
  • Datenblattüberprüfung: Entry-Level STM32 Cortex-M0 Microcontroller (Blog + Video)
  • Introduction to the Ultra High-Performance STM32H7 32-bit Microcontroller
4.52votes
Article Rating

Schreibe einen Kommentar

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