I den här djupgående artikeln lär du dig att utveckla inbäddad firmware för STM32 Cortex-m 32-bitars mikrokontroller med hjälp av de olika utvecklingsverktygen.
STM32-serien är några av de mest populära mikrokontroller som används i en mängd olika produkter. De har också en utmärkt supportbas från flera utvecklingsforum för mikrokontroller.
denna familj av mikrokontroller från STMicroelectronics är baserad på ARM Cortex-M 32-bitars processorkärna.
STM32 mikrokontroller erbjuder ett stort antal seriella och parallella kommunikationsutrustning som kan kopplas till alla typer av elektroniska komponenter inklusive sensorer, skärmar, kameror, motorer etc. Alla STM32-varianter levereras med internt flashminne och RAM.
utbudet av prestanda som finns med STM32 är ganska expansivt. Några av de mest grundläggande varianterna inkluderar underserien STM32F0 och STM32F1 som börjar med en klockfrekvens på endast 24 MHz och finns i paket med så få som 16 stift.
vid den andra performance extreme arbetar STM32H7 med upp till 400 MHz och finns i paket med så många som 240 stift.
de mer avancerade modellerna finns med Flytpunktsenheter (FPU) för applikationer med allvarliga numeriska bearbetningskrav. Dessa mer avancerade modeller suddar ut linjen mellan en mikrokontroller och en mikroprocessor.
slutligen är stm32l-underserien utformad speciellt för bärbara applikationer med låg effekt som körs från ett litet batteri.
utvecklingsverktyg
utvecklingsverktyg krävs för att utveckla koden, programmera mikrokontroller och testa/felsöka koden. Utvecklingsverktygen inkluderar:
- kompilator
- Debugger
- In-Circuit Serial Programmer (ICSP)
Programmering av STM32 via In-Circuit-Serial-Programmer (ICSP).
det finns flera mjukvaruutvecklingsverktyg tillgängliga för kodutveckling på STM32-mikrokontroller. Programvaruverktygen finns som integrerade utvecklingsmiljöer (ide) som kombinerar alla nödvändiga verktyg i en integrerad miljö.
två vanliga utvecklingspaket inkluderar:
- Keil MDK ARM (uVison5 IDE) – MDK ARM IDE är en mycket stabil utvecklingsmiljö som kan laddas ner gratis. Det möjliggör utveckling av kod upp till en programstorlek på 32 KB. För att utveckla större program måste en licensierad version köpas här.
- CoIDE-en gratis verktygskedja som är baserad på en trimmad version av Eclipse IDE integrerad tillsammans med en inbäddad ARM-version av den fria GCC-kompilatorn.
det finns också flera andra IDE: er som är tillgängliga för användning med STM32-mikrokontroller. Denna artikel fokuserar dock på att utveckla och blinka ett program med den mycket populära Keil MDK ARM uVision5 IDE.
förutom programvaruverktygen krävs en seriell programmerare (ICSP) för att programmera och testa koden på den faktiska mikrokontroller. ICSP krävs för att ansluta mikrokontroller till PC – programvaruverktygen via en USB-port.
ARM Cortex-m-mikrokontrollerna stöder två programmeringsprotokoll: JTAG (namngiven av electronics industry association The Joint Test Action Group) och Serial Wire Debug (SWD).
det finns flera ICSP-programmerare tillgängliga som stöder dessa protokoll, inklusive:
- Keil U-Link 2
- Segger J-Link
- ST-Link
utveckla den första applikationen
det är alltid lättast att börja med en lättillgänglig grundläggande kodram. Lägg sedan till koden som krävs för den specifika applikationen och modellen för mikrokontroller.
lyckligtvis ger STMicroelectronics ett mycket användbart grafiskt verktyg som heter STM32CubeMx som hjälper till att skapa ett grundläggande applikationsprojekt för alla STM32-mikrokontroller du väljer. Det kan också användas för att konfigurera kringutrustning på multiplexerade stiften i mikrokontroller.
stm32cubemx-verktyget kan laddas ner härifrån. STM32Cube levereras med en omfattande uppsättning drivrutiner för alla typer av kringutrustning och stöd för ett valfritt FreeRTOS (ett gratis realtidsoperativsystem) förintegrerat med koden.
följande avsnitt beskriver i detalj hur man skapar en enkel UART-applikation för stm32f030-mikrokontroller som ekar vad som skrivs i ett terminalfönster.
- installera stm32cubemx-programvaran.
- kör programmet och välj Nytt projekt. Det öppnar sedan MCU-Väljarfönstret som visas nedan.
- dubbelklicka för att välja den mikrokontrollermodell som används. I det här fallet använder vi STM32F030K6. Det tar dig sedan till pinout-sidan för den valda mikrokontroller.
STM32F030K6 är en ARM Cortex-M0-kärna med 32kB flashminne och 4KB RAM-minne. Exempelkoden möjliggör UART som använder PA9-och PA10-stiften för att ta emot och överföra seriell data som visas nedan med de gröna stiften.
konfigurera UART-inställningarna under fliken Konfiguration och välj UART-inställningarna som visas nedan. Aktivera alternativet NVIC global interrupt under fliken NVIC Settings.
navigera sedan till Project – >inställningar för att lägga till det nya projektnamnet och välj verktygskedjan IDE som ska användas. I det här exemplet anger du projektnamnet till ’UARTEcho’ och väljer Keil-MDK5 IDE för projektutvecklingen.
slutligen generera projektkoden genom att klicka på projekt -> generera kod.
bygga och blinka koden
Öppna nu den genererade MDK-ARM-projektfilen UARTEcho \ MDK-ARM \ UartEcho.uprojx.
detta program hittills initierar bara UART-periferin och stannar i en oändlig slinga.
det är viktigt att notera att STM32Cube genererar /* användarkod börjar x */ och /* användarkod slut x */ kommentar block för att genomföra den användarspecifika koden. Användarkoden måste skrivas i dessa kommentarblock. När koden genereras igen med modifierade konfigurationer behåller stmcube-verktyget användarkoden inom dessa användarkommentarblock.
definiera sedan en global variabel för att ta emot en byte från UART i huvudet.C källfil:
/* USER CODE BEGIN PV *//* Private variables ———————————————————*/static uint8_t recv_data;/* USER CODE END PV */
Efter alla initieringskoden, aktivera drivrutinen för att ta emot 1 byte. Följande funktion aktiverar rxne-avbrottsbiten.
/* USER CODE BEGIN 2 */HAL_UART_Receive_IT(&huart1, &recv_data, 1);/* USER CODE END 2 */
lägg nu till en återuppringningsfunktion för att hantera mottagningsavbrottet och överföra den mottagna byten.
/* USER CODE BEGIN 0 */void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart){HAL_UART_Transmit(huart, huart->pRxBuffPtr, 1, 1000);}/* USER CODE END 0 */
Slutligen måste vi kompilera koden och blinka (ladda ner) den till mikrokontroller.
När Keil MDK ARM IDE är installerat finns drivrutiner för ST-LINK V2, J-Link och Ulink2 tillgängliga. St-Link debugger kommer att väljas som standard. Gå till projekt – >alternativ för Target och på fliken Debug väljer du den använda ICSP-programmeraren.
blinka koden genom att välja Flash->ladda ner.
mikrokontrollern kommer nu att echo Alla data som mottas över UART. Den kan anslutas till en dator med hjälp av en USB-till-seriell omvandlare. På datorn öppnar du COM-porten med en terminalapplikation med inställningarna 115200-8-N-1. Nu kommer allt som skickas från terminalen att eka tillbaka genom mikrokontroller.
Avbrottssystem
STM32-avbrottssystemet är baserat på ARM Cortex m-kärnan NVIC perifer. STM32 MCU: erna stöder flera maskerbara avbrottskanaler bortsett från ARMKÄRNANS 16 avbrottskanaler.
till exempel stöder STM32F0 MCU-serien 32 maskerbara avbrott. Undantaget och avbrottstabellen för denna familj av MCU: er anges i tabellen nedan.
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)
STM32 MCU: erna har en utökad interrupts and Events controller som hanterar externa och interna asynkrona händelser/avbrott och genererar händelsebegäran till CPU / Interrupt Controller och en wake-up request till Power Manager.
var och en av de en eller flera EXTI-linjerna mappas till en av NVIC-avbrottvektorerna.
för de externa avbrotts linjer, för att generera ett avbrott, bör avbrotts linjen konfigureras och aktiveras. Detta görs genom att programmera de två triggerregistren med önskad kantdetektering och genom att aktivera avbrottsförfrågan genom att skriva en ’1’ till motsvarande bit i avbrottsmask registret.
externt avbrott och GPIO-mappning
var och en av de GPIO som finns tillgängliga på systemet kan konfigureras för att generera ett avbrott. Men var och en av EXTI-avbrottlinjerna är mappad till flera GPIO-stift. Till exempel PIO0 på alla tillgängliga GPIO-portar (A,B,C, etc.) kommer att mappas till EXTI0-linjen. PIO1 för alla portar kommer att mappas till EXTI1-linjen och så vidare.
några av EXTI-linjerna kombineras till en enda NVIC-vektor. Till exempel mappas EXTI4_15 till en enda vektoradress så det kommer att finnas en enda avbrottrutin för alla avbrott från PIO4 till PIO15. Men källan till avbrottet kan identifieras genom att läsa det pågående avbrottregistret.
en viktig sak att tänka på när man utformar ett system med STM32 MCU: er är valet av GPIO-stiften för avbrotten. MCU kan ha mer än 16 GPIO tillgängliga på enheten men det finns bara 16 externa avbrottlinjer tillgängliga.
EXTI_0 kan till exempel mappas till antingen PA0 eller PB0 men inte båda. Så när du väljer stiften för externa avbrott bör de väljas så att de kan unikt mappas till en av EXTI-linjerna.
i följande avsnitt beskrivs hur du konfigurerar ett avbrott med STM32-kuben.
Välj fliken Konfiguration och välj hårdvarumodulen för vilken avbrottet måste konfigureras. Modulkonfigurationsfönstret öppnas.
välj sedan fliken NVIC-inställningar och aktivera det globala avbrottet.
koden för att aktivera avbrottet för modulen genereras i stm32f0xx_hal_msp.c i HAL_<modul> _mspinit(…) funktion.
/* USART1 interrupt Init */HAL_NVIC_SetPriority(USART1_IRQn, 0, 0);HAL_NVIC_EnableIRQ(USART1_IRQn);
koden som genereras av STM32-kuben kommer att ha irq_handler-implementeringen av alla avbrott. När avbrottet är aktiverat kommer koden att inkluderas i applikationen.
vanligtvis hanterar den genererade koden redan IRQ och rensar flaggan som genererade avbrottet. Det kallar sedan ett program återuppringning som motsvarar den händelse som genererade avbrott för modulen.
STM32 Hal (Hardware Abstraction Layer) implementerar en återuppringning för var och en av händelsetyperna inom varje modul som en del av drivrutinen. I det här exemplet ska Rx Transfer Complete callback kopieras från stm32f0xx_hal_UART.C-fil.
återuppringningsfunktionerna i drivrutinen kommer att implementeras med ett _ _ svagt länkarattribut. Användaren måste implementera en kopia av den nödvändiga återuppringningsfunktionen genom att ta bort attributet __svag i en av applikationsfilerna och sedan skriva den specifika hantering som krävs inom den funktionen.
/*** @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.*/}
slutsats
denna handledning är en introduktion till att skriva en applikation som fungerar med STM32-familjen av mikrokontroller. Det finns flera andra metoder för att skriva en ansökan men stm32cube diskuteras är en enkel och intuitiv metod för att komma igång.
detta verktyg förenklar initialiseringen av kringutrustning till mikrokontroller. Det förbättrar också kodens underhåll, särskilt när det finns hårdvaruversioner som kräver ommappning av signalerna till olika stift.
en annan fördel med att använda STM32Cube-verktyget är att det genererar en rapport om användarkonfigurationen för mikrokontroller. I den här rapporten beskriver den klockträdet, pin-kartläggningen och hårdvarumodulkonfigurationen som alla är mycket användbara.
det finns också flera andra kodbibliotek och exempelprogram tillgängliga för alla STM32-varianter. Stöd för flera IDEs ingår också.
om ditt projekt kräver en sofistikerad 32-bitars mikrokontroller rekommenderar jag starkt STM32-serien. Inte bara är de kraftfulla och populära, men STM32 mikrokontroller är också ganska överkomliga.
behöver du mer utbildning om programmering av STM32-mikrokontroller? Om så är fallet, här är en mer djupgående introduktionskurs som du bör kolla in.
denna artikel är skriven av Mohan Kashivasi från Vithamas Technologies. Han är också en av de experter som finns tillgängliga för att hjälpa dig med din produkt inom Hardware Academy.
slutligen, glöm inte att ladda ner din gratis PDF: Ultimate Guide för att utveckla och sälja din nya elektroniska hårdvaruprodukt. Du kommer också att få mitt veckobrev där jag delar premiuminnehåll som inte är tillgängligt på min blogg.
annat innehåll du kanske gillar:
- introduktion till Stm32cubeide för STM32 mikrokontroller
- så här väljer du mikrokontroller för din nya produkt
- använda Arduino som en inbäddad utvecklingsplattform
- datablad granskning: Entry-Level STM32 Cortex-M0 Microcontroller (Blog + Video)
- Introduction to the Ultra High-Performance STM32H7 32-bit Microcontroller