Wprowadzenie do programowania 32-bitowych mikrokontrolerów STM32 ARM Cortex-m

w tym szczegółowym artykule dowiesz się, jak tworzyć wbudowane oprogramowanie układowe dla 32-bitowych mikrokontrolerów STM32 Cortex-m przy użyciu różnych narzędzi programistycznych.

mikrokontroler STM32

77 akcji

seria STM32 to jedne z najpopularniejszych mikrokontrolerów stosowanych w szerokiej gamie produktów. Mają również doskonałą bazę wsparcia z wielu forów programistycznych mikrokontrolerów.

ta rodzina mikrokontrolerów firmy STMicroelectronics oparta jest na 32-bitowym rdzeniu procesora ARM Cortex-M.

mikrokontrolery STM32 oferują dużą liczbę szeregowych i równoległych peryferii komunikacyjnych, które mogą być połączone z wszelkiego rodzaju komponentami elektronicznymi, w tym czujnikami, wyświetlaczami, kamerami, silnikami itp. Wszystkie warianty STM32 są wyposażone w wewnętrzną pamięć Flash i RAM.

zakres wydajności dostępny w STM32 jest dość rozległy. Niektóre z najbardziej podstawowych wariantów obejmują pod-serie STM32F0 i stm32f1, które zaczynają się z częstotliwością zegara tylko 24 MHz i są dostępne w pakietach z zaledwie 16 pinami.

przy innych ekstremalnych osiągach, stm32h7 działa z częstotliwością do 400 MHz i jest dostępny w pakietach z aż 240 pinami.

bardziej zaawansowane modele są dostępne z jednostkami Zmiennoprzecinkowymi (FPU) dla aplikacji o poważnych wymaganiach przetwarzania numerycznego. Te bardziej zaawansowane modele rozmywają linię między mikrokontrolerem a mikroprocesorem.

wreszcie, pod-seria STM32L została zaprojektowana specjalnie do zastosowań przenośnych o małej mocy, działających z małej baterii.

narzędzia programistyczne

narzędzia programistyczne są wymagane do opracowania kodu, zaprogramowania mikrokontrolera i przetestowania/debugowania kodu. Do narzędzi programistycznych należą:

  • kompilator
  • Debugger
  • In-Circuit Serial Programmer (ICSP)
Programowanie STM32

Programowanie STM32 za pomocą In-Circuit-Serial-Programmer (ICSP).

istnieje kilka narzędzi programistycznych dostępnych do tworzenia kodu na mikrokontrolerach STM32. Narzędzia programowe są dostępne jako zintegrowane Środowiska programistyczne (IDE), które łączy wszystkie niezbędne narzędzia w zintegrowane środowisko.

dwa popularne pakiety programistyczne obejmują:

  • Keil MDK ARM (UVISON5 IDE) – MDK ARM IDE jest bardzo stabilnym środowiskiem programistycznym, które można pobrać za darmo. Umożliwia tworzenie kodu do wielkości programu 32 KB. Do tworzenia większych programów należy zakupić tutaj licencjonowaną wersję.
  • CoIDE-darmowy łańcuch narzędzi, który bazuje na skróconej wersji Eclipse IDE zintegrowanej wraz z wbudowaną wersją ARM wolnego kompilatora GCC.

istnieje również kilka innych ID, które są dostępne do użytku z mikrokontrolerami STM32. Jednak ten artykuł skupia się na rozwijaniu i flashowaniu programu przy użyciu bardzo popularnego Keil MDK ARM UVISION5 IDE.

oprócz narzędzi programowych, do programowania i testowania kodu na rzeczywistym mikrokontrolerze wymagany jest programator szeregowy (In-Circuit Serial Programmer, ICSP). ICSP jest wymagany do podłączenia mikrokontrolera do narzędzi programowych komputera za pośrednictwem portu USB.

mikrokontrolery ARM Cortex-m obsługują dwa protokoły programowania: JTAG (nazwany przez Stowarzyszenie przemysłu elektronicznego Joint Test Action Group) i Serial Wire Debug (SWD).

dostępnych jest kilka programistów ICSP obsługujących te protokoły, w tym:

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

Tworzenie pierwszej aplikacji

zawsze najłatwiej jest zacząć od łatwo dostępnego podstawowego frameworka kodu. Następnie dodaj kod, który jest wymagany dla konkretnej aplikacji i modelu mikrokontrolera.

na szczęście STMicroelectronics dostarcza bardzo przydatne narzędzie graficzne o nazwie STM32CubeMx, które pomaga w tworzeniu podstawowego projektu aplikacji dla dowolnego mikrokontrolera STM32. Może być również używany do konfiguracji urządzeń peryferyjnych na multipleksowanych pinach mikrokontrolera.

narzędzie STM32CubeMX można pobrać stąd. STM32Cube jest wyposażony w obszerny zestaw sterowników dla wszystkich typów urządzeń peryferyjnych i obsługuje opcjonalny FreeRTOS (darmowy system operacyjny czasu rzeczywistego) wstępnie zintegrowany z kodem.

w poniższej sekcji szczegółowo opisano, jak stworzyć prostą aplikację UART dla mikrokontrolera STM32F030, która będzie odtwarzać wszystko, co jest wpisane w oknie terminala.

  • Zainstaluj oprogramowanie STM32CubeMX.
  • Uruchom aplikację i wybierz nowy projekt. Następnie otworzy okno wyboru MCU, jak pokazano poniżej.
  • Kliknij dwukrotnie, aby wybrać model mikrokontrolera. W tym przypadku używamy stm32f030k6. Następnie przechodzi do strony wyprowadzenia wybranego mikrokontrolera.

zrzut ekranu podczas konfigurowania nowego projektu w STM32CubeMX

STM32F030K6 to rdzeń ARM Cortex-M0 z 32KB pamięci Flash i 4KB pamięci RAM. Przykładowy kod umożliwia UART, który używa pinów PA9 i PA10 do odbierania i przesyłania danych szeregowych, jak pokazano poniżej za pomocą zielonych pinów.

zrzut ekranu pokazujący pinout dla STM32F030K6 w STM32CubeMX

skonfiguruj ustawienia UART w zakładce Konfiguracja i wybierz Ustawienia UART, jak pokazano poniżej. Włącz opcję globalnego przerwania nvic na karcie Ustawienia Nvic.

zrzut ekranu pokazujący jak skonfigurować ustawienia UART stm32cubemx

następnie przejdź do projektu–>Ustawienia, aby dodać nową nazwę projektu i wybrać IDE łańcucha narzędzi, które ma być używane. W tym przykładzie Ustaw nazwę projektu na „UARTEcho” i wybierz Keil-MDK5 IDE dla rozwoju projektu.

na koniec Wygeneruj kod projektu klikając Project- > Wygeneruj kod.

Budowanie i flashowanie kodu

teraz otwórz wygenerowany plik projektu MDK-ARM UARTEcho\MDK-ARM\UARTECHO.uprojx.

Ten program do tej pory tylko inicjalizuje UART i zatrzymuje się w nieskończonej pętli.

należy pamiętać, że STM32Cube generuje bloki /* kod użytkownika BEGIN X */ i /* Kod użytkownika END X */ comment, aby zaimplementować kod specyficzny dla użytkownika. Kod użytkownika musi być zapisany w tych blokach komentarzy. Za każdym razem, gdy kod jest ponownie generowany ze zmodyfikowanymi konfiguracjami, narzędzie STMCube zachowuje kod użytkownika w tych blokach Komentarzy Użytkownika.

następnie zdefiniuj zmienną globalną, aby otrzymać bajt z UART w głównej.c plik źródłowy:

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

po całym kodzie inicjalizacyjnym włącz sterownik, aby otrzymał 1 bajt. Poniższa funkcja włącza bit przerwania RXNE.

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

teraz Dodaj funkcję zwrotną do obsługi przerwania odbioru i transmisji odebranego bajtu.

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

na koniec musimy skompilować kod i flashować go (pobrać) do mikrokontrolera.

Po zainstalowaniu Keil MDK ARM IDE dostępne są sterowniki dla ST-LINK V2, J-Link i Ulink2. Debugger ST-Link zostanie wybrany domyślnie. Przejdź do projektów->opcje dla Target i w zakładce Debug wybierz używany programator ICSP.

Flashuj kod wybierając Flash- > Pobierz.

Uwaga: Pamiętaj, aby pobrać bezpłatny przewodnik PDF 15 kroków, aby opracować nowy produkt sprzętu elektronicznego.

mikrokontroler będzie teraz echo wszystkich danych odebranych przez UART. Można go podłączyć do komputera za pomocą konwertera USB-to-Serial. Na komputerze otwórz port COM za pomocą aplikacji terminalowej za pomocą ustawień 115200-8-N-1. Teraz wszystko, co zostanie wysłane z terminala, wróci echem przez mikrokontroler.

System przerwań

System przerwań STM32 oparty jest na rdzeniu ARM Cortex M nvic peripheral. MCU STM32 obsługują wiele maskowalnych kanałów przerwań, oprócz 16 kanałów przerwań rdzenia ARM.

na przykład seria MCU STM32F0 obsługuje 32 maskowalne przerwania. Tabela wyjątków i wektorów przerwań dla tej rodziny MCU jest podana w poniższej tabeli.

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 Kontroler przerwań i zdarzeń (EXTI)

MCU STM32 mają rozszerzony kontroler przerwań i zdarzeń, który zarządza zewnętrznymi i wewnętrznymi asynchronicznymi zdarzeniami/przerwaniami i generuje żądanie zdarzenia do kontrolera CPU/przerwań oraz żądanie budzenia do Menedżera zasilania.

każda z jednej lub więcej linii EXTI jest odwzorowana na jeden z wektorów przerwania NVIC.

dla zewnętrznych linii przerwań, aby wygenerować przerwanie, linia przerwań powinna być skonfigurowana i włączona. Odbywa się to poprzez zaprogramowanie dwóch rejestrów wyzwalania z żądaną detekcją krawędzi i włączenie żądania przerwania przez zapisanie '1′ do odpowiedniego bitu w rejestrze maski przerwań.

zewnętrzne przerwanie i mapowanie GPIO

każdy z GPIO dostępnych w systemie może być skonfigurowany do generowania przerwania. Ale każda z linii przerwań EXTI jest odwzorowana na wiele pinów GPIO. Na przykład, PIO0 na wszystkich dostępnych portów GPIO (A,B, C, itp.) zostanie zmapowany do linii EXTI0. PIO1 dla wszystkich portów będzie mapowany do linii EXTI1 i tak dalej.

niektóre z linii EXTI są połączone w jeden wektor NVIC. Na przykład, EXTI4_15 jest mapowany na pojedynczy adres wektorowy, więc będzie jedna procedura przerwania dla wszystkich przerwań z PIO4 do PIO15. Ale źródło przerwania może być zidentyfikowane przez odczyt rejestru przerwania oczekującego.

jedną ważną rzeczą, którą należy wziąć pod uwagę podczas projektowania systemu wykorzystującego MCU STM32, jest wybór pinów GPIO dla przerwań. MCU może mieć więcej niż 16 GPIOs dostępnych na urządzeniu, ale dostępnych jest tylko 16 zewnętrznych linii przerwań.

na przykład, EXTI_0 może być zmapowany do PA0 lub PB0, ale nie do obu. Tak więc przy wyborze pinów dla zewnętrznych przerwań powinny być tak dobrane, aby mogły być jednoznacznie odwzorowane na jedną z linii EXTI.

poniższa sekcja opisuje jak skonfigurować przerwanie za pomocą kostki STM32.

zrzut ekranu konfigurowanie przerwania stm32cubemx

wybierz zakładkę Konfiguracja i wybierz moduł sprzętowy, dla którego ma być skonfigurowane przerwanie. Zostanie otwarte okno konfiguracji modułu.

następnie wybierz kartę Ustawienia NVIC i włącz globalne przerwanie.

kod włączający przerwanie dla modułu zostanie wygenerowany w stm32f0xx_hal_msp.c w funkcji HAL_<modułu>_mspinit (…).

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

kod wygenerowany przez kostkę STM32 będzie miał implementację IRQ_Handler wszystkich przerwań. Po włączeniu przerwania kod zostanie dołączony do aplikacji.

Zwykle wygenerowany kod obsługuje już IRQ i czyści flagę, która wygenerowała przerwanie. Następnie wywołuje wywołanie zwrotne aplikacji, które odpowiada zdarzeniu, które wygenerowało przerwanie dla modułu.

HAL STM32 (Hardware Abstraction Layer) implementuje wywołanie zwrotne dla każdego typu zdarzeń w każdym module jako część sterownika. W tym przykładzie RX Transfer Complete callback powinien zostać skopiowany z stm32f0xx_hal_uart.plik C.

funkcje zwrotne wewnątrz sterownika będą zaimplementowane z atrybutem __weak linker. Użytkownik musi zaimplementować kopię niezbędnej funkcji zwrotnej, usuwając atrybut _ _ weak w jednym z plików aplikacji, a następnie zapisując określoną obsługę wymaganą w tej funkcji.

/*** @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.*/}

wnioski

Ten poradnik jest wprowadzeniem do pisania aplikacji, która współpracuje z rodziną mikrokontrolerów STM32. Istnieje kilka innych metod pisania aplikacji, ale omawiany STM32Cube jest łatwą i intuicyjną metodą na rozpoczęcie pracy.

To narzędzie upraszcza inicjalizację urządzeń peryferyjnych mikrokontrolera. Poprawia to również łatwość obsługi kodu, zwłaszcza gdy występują zmiany sprzętowe, które wymagają ponownego mapowania sygnałów na różne piny.

Kolejną zaletą korzystania z narzędzia STM32Cube jest to, że generuje on raport konfiguracji użytkownika dla mikrokontrolera. W tym raporcie szczegółowo opisano drzewo zegarów, mapowanie pinów i konfigurację modułów sprzętowych, które są bardzo przydatne.

istnieje również kilka innych bibliotek kodu i przykładowe programy dostępne dla wszystkich wariantów STM32. Wsparcie dla kilku IDE jest również włączone.

Jeśli twój projekt wymaga zaawansowanego 32-bitowego mikrokontrolera, to Gorąco polecam serię STM32. Nie tylko są potężne i popularne, ale mikrokontrolery STM32 są również dość przystępne cenowo.

Potrzebujesz więcej szkoleń z programowania mikrokontrolerów STM32? Jeśli tak, oto bardziej dogłębny kurs wprowadzający, który powinieneś sprawdzić.

Ten artykuł został napisany przez Mohan Kashivasi z Vithamas Technologies. Jest również jednym z ekspertów, którzy pomogą Ci z produktem w Akademii sprzętu.

na koniec nie zapomnij pobrać darmowego pliku PDF: Najlepszy przewodnik do opracowania i sprzedaży nowego produktu sprzętu elektronicznego. Będziesz także otrzymywać mój cotygodniowy newsletter, w którym udostępniam treści premium niedostępne na moim blogu.

inne treści, które mogą ci się spodobać:

  • Wprowadzenie do Stm32cubeide dla mikrokontrolerów STM32
  • Jak wybrać mikrokontroler dla nowego produktu
  • używanie Arduino jako wbudowanej Platformy Programistycznej
  • przegląd arkusza danych: Entry-Level STM32 Cortex-M0 Microcontroller (Blog + Video)
  • Introduction to the Ultra High-Performance STM32H7 32-bit Microcontroller
4.52votes
Article Rating

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany.