Programiranje STM32F4. Kreiranje novog projekta u Keilu. STM32F407(STM32F4-DISCOVERY) - Nestandardni pristup - Standardna biblioteka dio 1

Do sada smo koristili standardnu ​​biblioteku kernela - CMSIS. Kako bismo konfigurirali port na željeni način rada, morali smo se obratiti kako bismo pronašli registar odgovoran za određenu funkciju, a također pretražili veliki dokument za druge informacije vezane za ovaj proces. Stvari će postati još bolnije i rutinskije kada počnemo raditi sa tajmerom ili ADC-om. Broj registara tamo je mnogo veći od broja I/O portova. Ručna konfiguracija oduzima mnogo vremena i povećava šanse za greške. Stoga mnogi ljudi radije rade sa standardnom perifernom bibliotekom - StdPeriph. Šta to daje? Jednostavno - nivo apstrakcije raste, ne morate da ulazite u dokumentaciju i uglavnom razmišljate o registrima. U ovoj biblioteci su svi režimi rada i parametri periferije MK opisani u obliku struktura. Sada, da biste konfigurirali periferni uređaj, trebate samo pozvati funkciju inicijalizacije uređaja s popunjenom strukturom.

Ispod je slika sa šematskim prikazom nivoa apstrakcije.

Radili smo sa CMSIS-om (koji je "najbliži" jezgri) da pokažemo kako mikrokontroler radi. Sljedeći korak je standardna biblioteka, koju ćemo sada naučiti kako koristiti. Slijede drajveri uređaja. Oni se shvataju kao *.c \ *.h datoteke koje pružaju pogodan softverski interfejs za kontrolu bilo kojeg uređaja. Na primjer, u ovom kursu ćemo vam pružiti drajvere za max7219 čip i esp8266 WiFi modul.

Standardni projekat će uključivati ​​sljedeće datoteke:


Prvo, naravno, ovo su CMSIS fajlovi koji omogućavaju standardnoj biblioteci da radi sa kernelom, o njima smo već govorili. Drugo, datoteke standardne biblioteke. I treće, korisnički fajlovi.

Datoteke biblioteke možete pronaći na stranici posvećenoj ciljnom MK-u (za nas je to stm32f10x4), u odjeljku Design Resources(u CooCox IDE, ove datoteke se preuzimaju iz spremišta razvojnog okruženja). Svaki periferni uređaj odgovara dvije datoteke - zaglavlju (*.h) i izvornom kodu (*.c). Detaljan opis možete pronaći u datoteci podrške koja se nalazi u arhivi sa bibliotekom na web stranici.

  • stm32f10x_conf.h - konfiguracijski fajl biblioteke. Korisnik može spojiti ili isključiti module.
  • stm32f10x_ppp.h - datoteka zaglavlja periferije. Umjesto ppp-a može postojati gpio ili adc.
  • stm32f10x_ppp.c - drajver perifernih uređaja napisan u C jeziku.
  • stm32f10x_it.h - datoteka zaglavlja koja uključuje sve moguće rukovaoce prekidima (njihove prototipove).
  • stm32f10x_it.c je datoteka izvornog koda šablona koja sadrži rutinu usluge prekida (ISR) za izuzetne situacije u Cortexu M3. Korisnik može dodati vlastite ISR-ove za periferne uređaje koji se koriste.

Standardna biblioteka i periferni uređaji imaju konvenciju u imenovanju funkcija i notacije.

  • PPP je akronim za periferne uređaje, kao što je ADC.
  • Datoteke sistema, zaglavlja i izvornog koda - počnite sa stm32f10x_.
  • Konstante koje se koriste u jednoj datoteci su definirane u toj datoteci. Konstante koje se koriste u više datoteka definirane su u datotekama zaglavlja. Sve konstante u perifernoj biblioteci najčešće se pišu VELIKIM slovima.
  • Registri se tretiraju kao konstante i nazivaju se i VELIKIM slovima.
  • Imena funkcija specifičnih za periferiju uključuju akronim, kao što je USART_SendData() .
  • Za konfiguriranje svakog perifernog uređaja koristi se struktura PPP_InitTypeDef, koja se prosljeđuje funkciji PPP_Init().
  • Za deinicijalizaciju (podesite vrijednost na zadanu vrijednost), možete koristiti funkciju PPP_DeInit().
  • Funkcija koja vam omogućava da omogućite ili onemogućite periferne uređaje zove se PPP_Cmd().
  • Funkcija za omogućavanje/onemogućavanje prekida naziva se PPP_ITConfig.

Ponovo možete vidjeti kompletnu listu u datoteci za podršku biblioteke. Sada prepišimo LED koji treperi koristeći standardnu ​​perifernu biblioteku!

Prije početka rada, pogledajmo datoteku stm32f10x.h i pronađemo red:

#define USE_STDPERIPH_DRIVER

Ako projekt konfigurirate od nule koristeći datoteke biblioteke iz preuzete arhive, morat ćete ukloniti komentare iz ovog reda. To će vam omogućiti korištenje standardne biblioteke. Ova definicija (makro) će naložiti pretprocesoru da uključi datoteku stm32f10x_conf.h:

#ifdef USE_STDPERIPH_DRIVER #include "stm32f10x_conf.h" #endif

Ovaj fajl sadrži module. Ako su vam potrebne samo određene, onemogućite ostale, to će uštedjeti vrijeme tokom kompilacije. Nama, kao što ste mogli pretpostaviti, trebaju RTC i GPIO moduli (međutim, u budućnosti će nam trebati i _bkp.h, _flash, _pwr.h, _rtc.h, _spi.h, _tim.h, _usart.h):

#include "stm32f10x_flash.h" // za init_pll() #include "stm32f10x_gpio.h" #include "stm32f10x_rcc.h"

Kao i prošli put, prvo morate omogućiti taktiranje porta B. To radi funkcija deklarirana u stm32f10x_rcc.h:

Void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState);

FunctionalState enum je definiran u stm32f10x.h:

Typedef enum (DISABLE = 0, ENABLE = !DISABLE) FunctionalState;

Hajde da deklarišemo strukturu za postavljanje naše noge (možete je pronaći u datoteci stm32f10x_gpio.h):

GPIO_InitTypeDef LED;

Sada ga moramo popuniti. Pogledajmo sadržaj ove strukture:

Typedef struct ( uint16_t GPIO_Pin; GPIOSpeed_TypeDef GPIO_Speed; GPIOMode_TypeDef GPIO_Mode; ) GPIO_InitTypeDef;

Sve potrebne enumeracije i konstante mogu se naći u istoj datoteci. Tada će ponovo napisana init_leds() funkcija poprimiti sljedeći oblik:

Void led_init() ( // Omogući taktiranje RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); // Deklariraj strukturu i popuni je GPIO_InitTypeDef LED; LED.GPIO_Pin = GPIO_Pin_0; LED.GPIO_Speed_de_de=GPIO_Speed_Speed ​​.GPIO_Speed; _PP; // Inicijalizirajte port GPIO_Init( GPIOB,&LED); )

Prepišimo main() funkciju:

Int main(void) ( led_init(); while (1) (GPIO_SetBits(GPIOB, GPIO_Pin_0); delay(10000000); GPIO_ResetBits(GPIOB, GPIO_Pin_0); kašnjenje(10000000); ) )

Glavna stvar je dobiti osjećaj za redoslijed inicijalizacije: uključite periferni sat, proglasite strukturu, popunite strukturu, pozovite metodu inicijalizacije. Drugi periferni uređaji se obično konfiguriraju na sličan način.

Već dugo, čak i jako dugo, nije bilo novih članaka o našem članku, tako da je vrijeme da nadoknadite korak 😉 Danas ćemo početi proučavati STM32F4. I, vjerovatno, krenut ćemo sa kreiranjem novog projekta za ove kontrolere, iako, da budem iskren, nisam htio pisati članak o tome, jer se ovdje stvara novi projekt, u principu, na isti način što se tiče STM32F103 (). Ali ipak se dešava da se pojave neke poteškoće sa STM32F4, pa ipak, razmotrimo ovaj proces detaljno)

Dakle, hajde da pokrenemo Keil, napravimo novi projekat - Projekat -> Novi projekat uVision. Novi projekat spremamo u neku fasciklu, a zatim će nam se tražiti da odaberemo mikrokontroler koji ćemo koristiti. Pa, birajmo, neka bude STM32F407VG:

Gotovo, u dijaloškom okviru koji se pojavi kliknite "Da" i prvi fajl će biti dodan našem projektu - startup_stm32f4xx.s. Kao i prije, koristit ćemo biblioteke CMSIS I Standardna periferna biblioteka, ali, naravno, već za STM32F4xx kontrolere. Stoga ih svakako trebamo preuzeti i dodati potrebne datoteke u naš još uvijek prazan projekat. Inače, više puta sam čuo od različitih ljudi da nailaze na neke „ne baš“ biblioteke za F4, a čak ni najjednostavniji projekat nije sastavljen. Ja se nisam susreo sa ovim, međutim, evo testiranih biblioteka koje i sam koristim:

Dakle, preuzeli smo ga, sve je spremno, sada dodajemo datoteke u projekat. Na slici se vidi šta će vam trebati:

Pa, priprema je završena, sada kreirajmo novu .c datoteku, koja će sadržavati naš kod. Idemo na Fajl->Novo, otvara se prazna datoteka u Keilu, kliknite Datoteka->Sačuvaj kao i spremite ga pod imenom test.c, na primjer. Prilikom spremanja ne zaboravite navesti ekstenziju datoteke (.c). Fajl je kreiran, sjajno, ali ga također moramo dodati našem projektu. Pa, zapravo, nema ništa komplikovano u tome 😉 Hajde da napišemo prazan program za testiranje u ovaj fajl:

#include "stm32f4xx.h" #include "stm32f4xx_rcc.h" #include "stm32f4xx_gpio.h" /*******************************************************************/ int main() ( dok (1 ) ( __NOP() ; ) ) /*******************************************************************/

Gotovo sve je spremno, ostaje samo pogledati postavke projekta - Projekat->Opcije za cilj… Otvara se prozor sa mnogo kartica, ovdje nas zanima samo nekoliko. Otvorite karticu C/C++ a u polje Definiraj upisujemo:

Pa, dole u polju morate dodati putanje apsolutno svim datotekama uključenim u projekat. Nakon što završite ovaj korak, možete pritisnuti F7 (Build) i projekat će biti izgrađen bez grešaka ili upozorenja. Kao što vidite, ništa komplikovano)

Ali generalno, ja lično radim stvari malo drugačije. Pogledajte koji je nedostatak ovog pristupa. Pa smo negdje skinuli CMSIS i SPL biblioteke, dodali fajlove iz ovih foldera, zapisali putanje do fajlova, sve je super. ALI! Projekat neće biti izgrađen na drugom računaru, jer su sve putanje apsolutne, odnosno upućuju na određene fascikle na vašem računaru. A na drugoj mašini ćete zapravo morati ponovo da izvršite korake da biste kreirali novi projekat. Ovo je ogroman minus. Zbog toga obično kreiram poseban folder za novi projekat, u njemu kreiram podfoldere za CMSIS, SPL i druge biblioteke koje se koriste, iu te foldere stavljam sve fajlove koji su mi potrebni u svakom konkretnom projektu. Na primjer, napravimo STM32F4_Test folder za naš novi projekat i sljedeće mape u njemu:

Sve potrebne fajlove koje smo dodali prilikom kreiranja projekta na početku članka sam stavio u fascikle CMSIS i SPL. Sada pokrećemo Keil, kreiramo novi projekat i spremamo ga u našu podmapu projekta tako da svi projektni fajlovi budu na jednom mjestu i ne izazivaju haos)

Projekt je kreiran, sada, kao i prije, jednostavno u njega dodajemo sve datoteke iz STM32F4_CMSIS i STM32F4_SPL foldera. Stavljamo našu testnu .c datoteku sa funkcijom main() u Source folder i dodajemo je projektu. Ostaje samo konfigurirati postavke =) Sve je isto - u polje za definiranje pišemo:

USE_STDPERIPH_DRIVER,STM32F4XX



Sastavljamo projekat - nema grešaka, let je normalan! U principu, na kraju smo dobili istu stvar, ali sada će se projekt odmah sastaviti na bilo kojem drugom računalu bez ikakvih problema, a ovo je vrlo zgodno i korisno) Apsolutno sve datoteke projekta sada se nalaze u blizini, u istoj mapi, a putevi su postali relativni i ne moraju se mijenjati.
To je sve, zapravo, u bliskoj budućnosti ćemo uraditi nešto da programiramo STM32F4, definitivno, pa se vidimo uskoro!;)

Cijeli projekat iz primjera članka -

U ovoj publikaciji pokušaću da se fokusiram na glavne tačke za brz početak rada sa STM32F10x mikrokontrolerima zasnovanim na biblioteci standardnih perifernih uređaja proizvodne kompanije STMicroelectronics.

Članak će koristiti Eclipse CDT kao razvojno okruženje. Budući da će glavni fokus biti na programskom kodu, možete bezbedno raditi sve manipulacije u Code::Blocks.

Opća struktura projekta za ARM mikrokontrolere je opisana u mom članku.

Ovdje ću vas ukratko podsjetiti da će vam za pravljenje projekta za ARM mikrokontrolere (posebno STM32F10x) biti potrebna linker skripta i C-Startup datoteka.

Linker skripta je datoteka sa uputstvima za postavljanje programskog koda i podataka u memoriju mikrokontrolera. Može narediti da se vaš programski kod učita u Flash programsku memoriju ili SRAM memoriju podataka.

Mikrokontroleri sa različitim količinama memorije programa i podataka zahtevaju različite skripte za raspored. Mogu se nabaviti od proizvođača mikrokontrolera - STMicroelectronics.
Raspakujte standardnu ​​perifernu biblioteku STM32F10x iz arhive ARM_Toolchain/Lib/stm32f10x_stdperiph_lib.zip.
Sadrži primjere projekata za različita razvojna okruženja (IAR EWB, Keil uVision, Atollic True Studio, itd.). Najbliži nam je Atollic True Studio, jer je modifikacija Eclipse-a.
Idite na direktorij Project/StdPeriph_Template/TrueSTUDIO, tamo postoji nekoliko poddirektorija čija imena odgovaraju nazivima razvojnih ploča STM3210x-EVAL.

Saznajte koja od ovih ploča koristi istu liniju mikrokontrolera kao i vaša. Kopirajte datoteku stm32_flash.ld iz odgovarajućeg direktorija u svoj projekat.

Također je moguće kreirati univerzalnu skriptu u kojoj će se mijenjati samo količina programske i podatkovne memorije u skladu sa mikrokontrolerom koji se koristi.

Početni kod (C-Startup) za STM32 mikrokontrolere može se napisati u C ili Assembleru.
Iako se standardna periferna biblioteka STM32F10x (skraćeno STM32F10x SPL) često kritikuje zbog svojih grešaka, to je najlakši način da brzo započnete kada započnete STM32 programiranje.
Ali uvijek želite da postoji neka vrsta alternative. Zapravo, ima ih mnogo, na primjer, programiranje na asembleru :)

Ovo je najteži i besmisleni put. Drugi način je korištenje CMSIS biblioteke, koja obezbjeđuje sintaksu za pristup strukturama jezika C za pristup raznim periferijama mikrokontrolera. Najjednostavniji i najlogičniji način (po mom mišljenju) je korištenje biblioteka.

Ako ste kategorički protiv STM32F10x SPL, onda postoji još jedna alternativa posebno za vas - biblioteka libopencm3. U njemu je većina primjera koncentrisana oko glavne serije mikrokontrolera STM32F10x, ali je samo pitanje vremena kada će se pojaviti primjeri za druge serije (STM32F2xx/4xx). Uvijek se možete pridružiti projektu libopencm3 i ubrzati ovaj proces.

CMSIS standard je također opcionalan za korištenje u vašim programima.
Možete i bez toga tako što ćete potrošiti malo truda i vremena da implementirate nivo HAL (Sloj hardverske apstrakcije) u programskom jeziku C.

Ova metoda može u nekim slučajevima biti jedina dostupna metoda. Na primjer, vaša organizacija koristi prilagođene čipove zasnovane na ARM-razvijenim računarskim jezgrama i perifernim uređajima specifičnim za industriju.

Ili trebate implementirati softver u C za mikrokontrolere sa ARM9 jezgrom, za koje se proizvođači fokusiraju na korištenje gotovih operativnih sistema (Linux, QNX, Windows CE), pa biblioteke za programiranje u C-u u čistom obliku ili u kombinaciji sa više lagani RTOS proizvođači ga možda neće obezbijediti.

Na sreću, proizvođači mikrokontrolera baziranih na Cortex-M3 jezgri pružaju programerima veliki broj biblioteka kodova. Ovo se odnosi i na STM32 mikrokontrolere.
Nastavimo sa razmatranjem STM32F10x SPL biblioteke. Razmotrit ćemo to na primjeru.
Možete otvoriti ovaj primjer ili kreirati vlastiti projekt od nule kako biste bolje razumjeli cijeli proces onoga što se događa.

Za drugi slučaj navest ću potrebne korake:

  • Kreirajte novi prazan projekat u Eclipseu
  • Kopirajte skriptu izgleda i startni fajl u projekat
  • Kreirajte novi ili kopirajte predložak Makefile
  • Kada koristite Makefile iz mog primjera kao predložak, trebate kreirati direktorije src, inc, bin, obj unutar projekta i kreirati poddirektorije Debug i Release unutar direktorija bin i obj.
  • Kopirajte potrebne izvorne datoteke i datoteke zaglavlja iz CMSIS i STM32F10x SPL biblioteka.
  • Napravite potrebne promjene u odjeljku korisničkih postavki u Makefileu predloška, ​​ako se koristi.
  • Kreirajte nove ciljeve “Debug”, “cleanDebug”, “Release”, “cleanRelease”, “Program” u Eclipse prozoru “make target”.
  • Pokrenite cilj „Debug” i pratite njegovo izvršenje u prozoru „Konzola”.

Radi boljeg razumijevanja materijala, podijelio sam članak u nekoliko nezavisnih paragrafa, od kojih svaki opisuje samo jedan aspekt rada sa bibliotekom STM32F10x SPL.

Konfiguriranje STM32F10x SPL korištenjem makro definicija

Za konfiguriranje biblioteke koriste se unaprijed definirane vrijednosti makroa, koje ćemo sada razmotriti.
Mogu se postaviti unutar datoteka zaglavlja pomoću direktive preprocesora #define ili proslijediti vrijednosti makro definicija kroz ključ -D GCC kompajler.
U mom primjeru koristim drugu metodu.
U Makefile varijablu DEFINE sadrži makroe potrebne za kompajliranje STM32F10x SPL biblioteke.
Makro definicija STM32F10X_MD specificira da li korišteni mikrokontroler pripada liniji Srednje gustine.
Ovo uključuje mikrokontrolere sa Flash memorijom od 64 do 128 kB.
Sljedeća tabela navodi nazive makroa za različite serije mikrokontrolera:

Naziv serije Makro Opis
Linija vrijednosti niske gustine STM32F10X_LD_VL sa kapacitetom fleš memorije 16 - 32 kB
Niska gustina STM32F10X_LD
sa kapacitetom fleš memorije 16 - 32 kB
Linija vrijednosti srednje gustine STM32F10X_MD_VL Fleš memorija
64 - 128kB
Srednje gustine STM32F10X_MD mikrokontroleri serije STM32F101xx, STM32F102xx, STM32F103xx sa Flash memorijom 64 - 128 kB
Visoka gustina Value line STM32F10X_HD_VL mikrokontroleri serije STM32F100xx sa zapreminom
Flash - memorija 256 - 512 kB
Velika gustoća STM32F10X_HD sa zapreminom
Flash memorija 256 - 512kB
XL-gustina STM32F10X_XL
Flash memorija 512 - 1024 kB
Linija za povezivanje STM32F10X_CL

Da biste podesili taktnu frekvenciju mikrokontrolera, morate dekomentirati makro sa potrebnom vrijednošću frekvencije takta u datoteci system_stm32f10x.c.

#ako je definirano (STM32F10X_LD_VL) || (definirano STM32F10X_MD_VL) || (definisano STM32F10X_HD_VL) #define SYSCLK_FREQ_24MHz 24000000 #else /* #define SYSCLK_FREQ_HSE HSE_VALUE */ /* #define SYSCLK_FREQ_24MHz 24000000 #else /* #define SYSCLK_FREQ_24MHz 24000000 */ /* #define SYSCLK_FREQ_24MHz 24000006* 0 0000 */ /* #define SYSCLK_FREQ_48MHz 48000000 */ /* #define SYSCLK_FREQ_56MHz 56000000 * / #define SYSCLK_FREQ_72MHz 72000000 #endif

#ako je definirano (STM32F10X_LD_VL) || (definirano STM32F10X_MD_VL) || (definirano STM32F10X_HD_VL)

/* #define SYSCLK_FREQ_HSE HSE_VALUE */

#define SYSCLK_FREQ_24MHz 24000000

#else

/* #define SYSCLK_FREQ_HSE HSE_VALUE */

/* #define SYSCLK_FREQ_24MHz 24000000 */

/* #define SYSCLK_FREQ_36MHz 36000000 */

/* #define SYSCLK_FREQ_48MHz 48000000 */

/* #define SYSCLK_FREQ_56MHz 56000000 */

#define SYSCLK_FREQ_72MHz 72000000

#endif

Pretpostavlja se da se koristi kvarcni rezonator sa frekvencijom od 8 MHz za sve glavne
serija mikrokontrolera, osim linije Connectivity, za koju je potrebno ugraditi kvarcni rezonator od 25 MHz.
Ako koristite kvarcne rezonatore s drugim vrijednostima frekvencije, tada morate promijeniti vrijednost makroa HSE_VALUE u datoteci zaglavlja stm32f10x.h i prilagoditi sve zavisne funkcije u skladu s tim.
Svrhu makroa USE_STDPERIPH_DRIVER nije teško pogoditi - koristiti standardnu ​​perifernu biblioteku STM32F10x.
USE_FULL_ASSERT – koristite ASSERT makro za otklanjanje grešaka u programu.

Korištenje makroa assert_param u biblioteci

Sve funkcije biblioteke STM32F10x SPL koriste makro assert_param za provjeru svojih argumenata.
Ovaj makro provjerava izraz koji uključuje argument funkcije koji se testira na jednakost nuli. Ako je vrijednost izraza nula, tada se poziva funkcija rukovanja greškom argumenta assert_failed, u suprotnom (izraz nije nula), provjera argumenta je uspješna.
Morate implementirati assert_failed funkciju u svoj program.
Prikazuje poruku o grešci, naziv datoteke i broj reda koda koji je uzrokovao grešku.
Makro debug_printf može da izlazi preko USART-a koristeći standardnu ​​biblioteku new_lib ili, na primjer, biblioteku gospodina Chena.

#define debug_printf xprintf /* printf */ #ifdef USE_FULL_ASSERT void assert_failed(uint8_t* datoteka, uint32_t linija) ( debug_printf("Pogrešna vrijednost parametara: datoteka %s na liniji %d\r\n", datoteka, (int)line) dok (1) ( ) )/* assert_failed */ #endif/*USE_FULL_ASSERT*/

#define debug_printf xprintf /* printf */

#ifdef USE_FULL_ASSERT

void assert_failed (uint8_t * datoteka, uint32_t linija)

debug_printf( "Pogrešna vrijednost parametara: datoteka %s na liniji %d\r\n", datoteka , (int ) red ) ;

dok (1)

) /* assert_failed */

#endif/*USE_FULL_ASSERT*/

Funkcija assert_failed implementirana u vašem kodu koristi se samo kada je deklariran makro USE_FULL_ASSERT. U suprotnom, sav kod za otklanjanje grešaka je isključen iz izvora. Ova funkcionalnost je implementirana u datoteku zaglavlja postavki biblioteke drajvera stm32f10x_conf.h.

#ifdef USE_FULL_ASSERT #define assert_param(expr) ((expr) ? (void)0: assert_failed((uint8_t *)__FILE__, __LINE__)) void assert_failed(uint8_t* datoteka, uint32_t linija); #else #define assert_param(expr) ((void)0) #endif /* USE_FULL_ASSERT */

#ifdef USE_FULL_ASSERT

#define assert_param(expr) ((expr) ? (void)0: assert_failed((uint8_t *)__FILE__, __LINE__))

void assert_failed (uint8_t * datoteka, uint32_t linija) ;

#else

#define assert_param(expr) ((void)0)

#endif /* USE_FULL_ASSERT */

Nema tu mnogo za objašnjavati. Pogledajmo primjer korištenja assert_param.

void set_param(uint8_t * param, uint8_t vrijednost) (assert_param(param != NULL); *param = vrijednost; )/*set_param*/

void set_param (uint8_t * param, uint8_t vrijednost)

assert_param (param != NULL) ;

* param = vrijednost;

) /*set_param*/

Funkcija postavlja vrijednost parametra preko pokazivača proslijeđenog kao argumenta. Ako makro USE_FULL_ASSERT nije deklarisan, onda možemo pretpostaviti da su linije
assert_param(param != NULL) jednostavno nije u kodu, inače se parametar provjerava u ovoj definiciji.
Ako pokazivač nije definiran, tada će vrijednost param != NULL biti lažna i pokrenut će se funkcija assert_failed, koja će ispisati ime datoteke i broj reda s greškom putem USART-a, a zatim napraviti petlju, čime se sprječava da vrijednost bude dodijeljen nedefiniranoj adresi u memoriji.
Od vas se uopće ne traži da koristite makro assert_param u svom kodu, već u kodu biblioteke
STM32F10x SPL koristi se svuda.
Funkcija set_param može se implementirati sa provjerom greške argumenta bez korištenja assert_param.

#define GREŠKA (-1) #define OK (0) int set_param(uint8_t * param, uint8_t vrijednost) (int r = GREŠKA; if (param == NULL) vrati r; *param = vrijednost; r = OK; return r ; )/*set_param*/

#define GREŠKA (-1)

#define OK (0)

int set_param (uint8_t * param, uint8_t vrijednost)

int r = GREŠKA;

if (param == NULL)

return r ;

* param = vrijednost;

r = OK ;

return r ;

) /*set_param*/

C-Startup datoteka u STM32F10x SPL biblioteci

U početnom kodu, mikrokontroler je inicijalno inicijaliziran, stek je konfigurisan, BSS sekcija se resetuje i poziva se glavna funkcija main().
Početni kod nema direktnu vezu sa STM32F10x SPL bibliotekom. Međutim, u ovom kodu za pokretanje, prije pozivanja funkcije main() programa, poziva se funkcija inicijalizacije mikrokontrolera SystemInit(), koja je dio CMSIS-a.
Može se lako pronaći u CMSIS biblioteci.
Idite u direktorij Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x/startup/TrueSTUDIO i kopirajte potrebnu datoteku. Ostaje samo da saznate kojoj liniji pripada mikrokontroler koji se koristi u vašem projektu.
Da biste to učinili, pogledajte sljedeću tabelu:

Naziv serije Ime dokumenta Opis
Linija vrijednosti niske gustine startup_stm32f10x_ld_vl.s mikrokontroleri serije STM32F100xx sa zapreminom
Flash memorija 16 - 32kB
Niska gustina startup_stm32f10x_ld.s mikrokontroleri serije STM32F101xx, STM32F102xx, STM32F103xx
sa kapacitetom fleš memorije 16 - 32 kB
Linija vrijednosti srednje gustine startup_stm32f10x_md_vl.s mikrokontroleri serije STM32F100xx
Srednje gustine startup_stm32f10x_md.s mikrokontroleri serije STM32F101xx, STM32F102xx, STM32F103xx
sa kapacitetom fleš memorije 64 - 128 kB
Visoka gustina Value line startup_stm32f10x_hd_vl.s mikrokontroleri serije STM32F100xx
Velika gustoća startup_stm32f10x_hd.s mikrokontroleri serije STM32F101xx, STM32F103xx
sa kapacitetom fleš memorije 256 - 512 kB
XL-gustina startup_stm32f10x_xl.s mikrokontroleri serije STM32F101xx, STM32F103xx
sa kapacitetom fleš memorije 512 - 1024 kB
Linija za povezivanje startup_stm32f10x_cl.s mikrokontroleri serije STM32F105xx i STM32F107xx

Datoteka pokretanja sadrži imena rukovaoca vektora prekida i izuzetaka, ali je implementiran samo rukovalac vektora resetovanja, u okviru kojeg se sva početna inicijalizacija obavlja prije poziva funkcije main().
Implementacija svih ostalih rukovatelja izuzetkom je odgovornost programera aplikacije. Ako vaš program ne koristi nikakve rukovatelje, nema potrebe da ih registrujete. Ako dođe do iznimke, koristit će se zadani rukovalac - petlja programskog koda.

Sastav CMSIS biblioteke

Kao što je ranije napisano u ovoj publikaciji, CMSIS biblioteka omogućava pristup perifernim modulima mikrokontrolera koristeći elemente struktura jezika C.
Implementacija ove biblioteke podijeljena je na dva dijela. Prvi dio omogućava pristup periferiji Cortex-M3 jezgre, a drugi - periferiji određenog modela mikrokontrolera.
Budući da je CMSIS standard isti za sve mikrokontrolere sa Cortex-M3 jezgrom, implementacija prvog dijela će biti ista za sve proizvođače, ali će drugi dio biti različit za svakog proizvođača.
CMSIS uključuje nekoliko zaglavlja i izvornih datoteka. Prvi dio uključuje fajlove:

  • core_cm3.h
  • core_cm3.c

Drugi dio CMSIS-a uključuje C-Startup datoteku, kao i sljedeće datoteke:

  • stm32f10x.h
  • system_stm32f10x.h
  • system_stm32f10x.c

Datoteka zaglavlja stm32f10x.h sadrži makro definicije za pristup perifernim modulima stm32f10x mikrokontrolera.
Datoteke system_stm32f10x.h i system_stm32f10x.c implementiraju početnu inicijalizaciju mikrokontrolera.

Sastav i konfiguracija STM32F10x SPL biblioteke

Biblioteka se sastoji od izvornih datoteka i datoteka zaglavlja istog imena kao i periferni moduli s prefiksom stm32f10x_.
Na primjer, implementacija interakcije sa USART modulom sadržana je u datotekama stm32f10x_usart.h i stm32f10x_usart.c.
Postoje konvencije za imenovanje elemenata biblioteke i određena pravila kodiranja, koja su opisana u dokumentaciji.
Biblioteka sadrži implementaciju drajvera za periferne mikrokontrolerske module.
Imena elemenata biblioteke koriste sljedeće akronime za periferne module:

Akronim Periferni modul
ADC analogno-digitalni pretvarač
BKP rezervne registre
CAN CAN interfejs
CEC kontroler potrošnje
CRC modul za izračunavanje kontrolne sume
DAC digitalno-analogni pretvarač
DBGMCU otklanjanje grešaka u mikrokontroleru
DMA kontroler direktnog pristupa memoriji
EXTI eksterni kontroler prekida
FSMC eksterni memorijski kontroler
FLASH Flash programska memorija
GPIO I/O portovi opšte namene
I2C I2C interfejs
I2S I2S (zvuk) interfejs
IWDG nezavisni watchdog tajmer
NVIC ugniježđeni kontroler prekida
PWR kontroler snage
RCC reset i kontroler sata
RTC kontroler u realnom vremenu (sat)
SDIO SDIO interfejs
SPI SPI interfejs
SysTick sistemski tajmer
TIM osnovni ili napredni tajmer
USART univerzalni serijski sinhroni-asinhroni
primopredajnik
WWDG prozor čuvar

Na osnovu ovih akronima formiraju se nazivi softverskih modula biblioteke. Ne morate koristiti sve module u biblioteci.
Da biste koristili samo potrebne module u projektu, biblioteka mora biti konfigurisana.
U ove svrhe, svaki projekt koji koristi STM32F10x SPL biblioteku mora imati datoteku zaglavlja stm32f10x_conf.h.

#include "stm32f10x_gpio.h" //#include "stm32f10x_i2c.h" //#include "stm32f10x_iwdg.h" //#include "stm32f10x_pwr.h" #include "stm32f10x_rcc.h"

#include "stm32f10x_gpio.h"

//#include "stm32f10x_i2c.h"

//#include "stm32f10x_iwdg.h"

//#include "stm32f10x_pwr.h"

#include "stm32f10x_rcc.h"

Da biste omogućili traženi modul, morate dekomentirati direktivu #include sa odgovarajućim datotekama zaglavlja.
Datoteka zaglavlja stm32f10x_conf.h je uključena u stm32f10x.h, tako da da biste koristili funkcije STM32F10x SPL biblioteke, trebate uključiti samo jednu datoteku zaglavlja stm32f10x.h u svoj izvorni kod

// u datoteci stm32f10x.h #ifdef USE_STDPERIPH_DRIVER #include "stm32f10x_conf.h" #endif

Ponavljam da projekat također mora definirati makroe USE_STDPERIPH_DRIVER, USE_FULL_ASSERT i makro koji specificira seriju mikrokontrolera koji se koristi (na primjer, STM32F10X_MD za liniju srednje gustine).
Ako koristite standardnu ​​vrijednost kvarcne frekvencije i kontroler radi na maksimalnoj frekvenciji takta od 72 MHz, tada nećete morati ništa više mijenjati.
Morate dodati listu datoteka biblioteke za kompajliranje u Makefile.
Na primjer:

SRC += stm32f10x_rcc.c SRC += stm32f10x_gpio.c

SRC += stm32f10x_rcc . c

SRC += stm32f10x_gpio . c

Korištenje STM32F10x SPL biblioteke. Radni mehanizmi

Da biste započeli programiranje koristeći perifernu biblioteku, najlakši način je da pogledate primjere isporučene s bibliotekom. Ali ipak, da biste razumjeli kod ovih primjera, morate imati osnovno znanje o sintaksi i korištenju biblioteke.
Svi prethodno navedeni periferni mikrokontrolerski moduli su inicijalno deaktivirani, ne dovodi im se takt signal i ne troše električnu energiju.
Da biste koristili periferni modul, prvo mu morate dati signal takta. Signal takta isporučuje RCC sat i modul za resetovanje.
U te svrhe biblioteka ima sljedeće funkcije:

RCC_AHBPeriphClockCmd(RCC_AHBPeriph_PPPx, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_PPPx, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_PPPx, ENABLE);

RCC_AHBPeriphClockCmd(RCC_AHBPeriph_PPPx, ENABLE);

RCC_APB2PeriphClockCmd (RCC_APB2Periph_PPPx, ENABLE) ;

RCC_APB1PeriphClockCmd (RCC_APB1Periph_PPPx, ENABLE) ;

Ovdje PPP označava naziv aktonima modula (na primjer ADC ili USART), a x je broj perifernog modula.
Prije svega, morate saznati na koju magistralu je spojen modul koji koristite.
Ukupno, mikrokontroleri sa Cortex-M3 arhitekturom jezgre imaju tri magistrale:
sabirnica instrukcija, sabirnica podataka i sistemska sabirnica. Sabirnica instrukcija povezuje jezgro sa Flash programskom memorijom. Sabirnice podataka i sistemske sabirnice su kombinovane u AHB (ARM Hi-Speed ​​Bus) matricu sabirnice, koja radi na frekvenciji jezgra. Međutim, frekvencija AHB sabirnice može se smanjiti ugradnjom razdjelnika. AHB magistrala povezuje uređaje velike brzine kao što su jezgra i DMA modul.
I/O uređaji su povezani na AHB sabirnicu preko srednjih sabirnica APB1 i APB2 (ARM periferna sabirnica).
Maksimalna radna frekvencija APB2 magistrale je 72 MHz, frekvencija APB1 magistrale
ograničen na 36MHz.
Na koju od sabirnica je povezan periferni modul koji koristite možete saznati iz dokumentacije ili pogledati u zaglavlju stm32f10x_rcc.h.
Otvorite ovu datoteku i potražite vrijednosti RCC_AHBPeriph, RCC_APB1Periph i RCC_APB2Periph redom.

#define RCC_AHBPeriph_DMA1 ((uint32_t)0x00000001) #define RCC_AHBPeriph_DMA2 ((uint32_t)0x00000002) #define RCC_AHBPeriph_SRAM ((uint32_0FLBe000000) (uint32_t) 0x00000010) #define RCC_AHBPeriph_CRC ((uint32_t)0x00000040)

#define RCC_AHBPeriph_DMA1 ((uint32_t)0x00000001)

#define RCC_AHBPeriph_DMA2 ((uint32_t)0x00000002)

#define RCC_AHBPeriph_SRAM ((uint32_t)0x00000004)

#define RCC_AHBPeriph_FLITF ((uint32_t)0x00000010)

#define RCC_AHBPeriph_CRC ((uint32_t)0x00000040)

Po imenima makroa određujemo koji su moduli povezani na koje sabirnice. Također možete koristiti zdrav razum da odredite koja guma pripada jednoj od tri. Na primjer, USART modul je ulazno/izlazni uređaj, što znači da je povezan na jednu od APB magistrala. USART je sučelje prilično male brzine, tako da je vjerovatno povezano na APB1 magistralu.

#define RCC_APB1Periph_USART2 ((uint32_t)0x00020000) #define RCC_APB1Periph_USART3 ((uint32_t)0x00040000) #define RCC_APB1Periph_UART4 ((uint0x300) _UART5 ((uint32_t)0x00100000)

Nakon slanja signala sata perifernom modulu, možete konfigurirati njegove parametre pozivanjem funkcije inicijalizacije:

PPP_Init(PPP, &PPP_InitStructure);

PPP_Init (PPP, & amp; PPP_InitStructure) ;

Budući da mnogi parametri moraju biti proslijeđeni funkciji inicijalizacije da bi se inicijalizirao periferni modul, kao argument se koristi pokazivač na strukturu. Sama struktura s parametrima inicijalizacije mora biti kreirana u memoriji prije pozivanja funkcije inicijalizacije; elementima strukture moraju biti dodijeljene potrebne vrijednosti:

PPP_InitTypeDef PPP_InitStructure = (val1, val2, ..., valN);/* inicijalizacija strukture kada je deklarirana */

Prvo možete kreirati strukturu, a zatim dodijeliti potrebne vrijednosti njenim elementima:

PPP_InitTypeDef PPP_InitStructure; PPP_InitStructure.member1 = val1; PPP_InitStructure.member2 = val2; PPP_InitStructure.memberN = valN;

PPP_InitTypeDef PPP_InitStructure ;

PPP_InitStructure . član1 = val1 ;

PPP_InitStructure . član2 = val2 ;

PPP_InitStructure . memberN = valN ;

Pogledajmo primjer iz projekta stm32f10xQuickstart:

GPIO_InitTypeDef GPIO_InitStructure; #ifdef USE_STM32H_103 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; GPIO_InitStructure.GPIO_Speed ​​= GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOC, &GPIO_InitStructure);

GPIO_InitTypeDef GPIO_InitStructure ;

#ifdef USE_STM32H_103

RCC_APB2PeriphClockCmd (RCC_APB2Periph_GPIOC, ENABLE) ;

GPIO_InitStructure . GPIO_Pin = GPIO_Pin_12;

GPIO_InitStructure . GPIO_Speed ​​= GPIO_Speed_50MHz;

GPIO_InitStructure . GPIO_Mode = GPIO_Mode_Out_PP ;

GPIO_Init(GPIOC, & GPIO_InitStructure);

Elementima strukture GPIO_InitStructure dodijeljena je vrijednost pin broja, načina rada i brzine porta.
Pozivanjem funkcije GPIO_Init, linija 12 GPIOC porta se inicijalizira.
Prvi argument funkcije GPIO_Init je pokazivač na memorijsku oblast GPIOC periferije, konvertovan u pokazivač na strukturu GPIO_TypeDef.

// stm32f10x.h #define GPIOC ((GPIO_TypeDef *) GPIOC_BASE) #define GPIOC_BASE (APB2PERIPH_BASE + 0x1000) #define APB2PERIPH_BASE (PERIPH_BASE + 0x1000t PERI_0) (0x1000000) 000) typedef struct ( __IO uint32_t CRL; __IO uint32_t CRH __IO uint32_t IDR; __IO uint32_t ODR; __IO uint32_t BSRR; __IO uint32_t BRR; __IO uint32_t LCKR; ) GPIO_TypeDef;

// stm32f10x.h

#define GPIOC ((GPIO_TypeDef *) GPIOC_BASE)

#define GPIOC_BASE (APB2PERIPH_BASE + 0x1000)

#define APB2PERIPH_BASE (PERIPH_BASE + 0x10000)

#define PERIPH_BASE ((uint32_t)0x40000000)

typedef struct

IO uint32_t CRL ;

IO uint32_t CRH ;

IO uint32_t IDR ;

IO uint32_t ODR ;

IO uint32_t BSRR ;

IO uint32_t BRR ;

IO uint32_t LCKR ;

) GPIO_TypeDef ;

Struktura GPIO_InitStructure je tipa GPIO_InitTypeDef, opisana u datoteci zaglavlja
stm32f10x_gpio.h:

//stm32f10x_gpio.h typedef struct ( uint16_t GPIO_Pin; GPIOSpeed_TypeDef GPIO_Speed; GPIOMode_TypeDef GPIO_Mode; )GPIO_InitTypeDef; typedef enum ( GPIO_Speed_10MHz = 1, GPIO_Speed_2MHz, GPIO_Speed_50MHz )GPIOSpeed_TypeDef; typedef enum ( GPIO_Mode_AIN = 0x0, GPIO_Mode_IN_FLOATING = 0x04, GPIO_Mode_IPD = 0x28, GPIO_Mode_IPU = 0x48, GPIO_Mode_Out_OD = 0x14, GPOxOD1_Mode = 0x14, GPUTIO_Mode C, GPIO_Mode_AF_PP = 0x18 )GPIOMode_TypeDef;

//stm32f10x_gpio.h

typedef struct

uint16_t GPIO_Pin ;

GPIOSpeed_TypeDef GPIO_Speed;

GPIOMode_TypeDef GPIO_Mode ;

) GPIO_InitTypeDef ;

typedef enum

GPIO_Brzina_10MHz = 1,

GPIO_Brzina_2MHz,

GPIO_Speed_50MHz

) GPIOSpeed_TypeDef ;

typedef enum

(GPIO_Mode_AIN = 0x0,

GPIO_Mode_IN_FLOATING = 0x04 ,

GPIO_Mode_IPD = 0x28,

GPIO_Mode_IPU = 0x48,

GPIO_Mode_Out_OD = 0x14,

GPIO_Mode_Out_PP = 0x10,

GPIO_Mode_AF_OD = 0x1C ,

GPIO_Mode_AF_PP = 0x18

) GPIOMode_TypeDef ;

Kao što možete vidjeti, i korisnički definirani tipovi, poput GPIOSpeed_TypeDef, i tipovi podataka sa specifičnim vrijednostima za praktičnost inicijalizacije perifernih registara, poput GPIOMode_TypeDef, mogu se koristiti kao tipovi podataka inicijalizirane strukture.
4 bita su dodijeljena za konfiguraciju svakog GPIO pina.
Sljedeća slika prikazuje format za nulti bit GPIO:

Mode – izlazni način rada (ulaz/izlaz). Preciznije, ove vrijednosti su nešto veće; portovi konfigurirani kao izlazni portovi imaju ograničenje na maksimalnu frekvenciju izlaznog signala.

Mode Opis
00 ulaz
01 izlazna frekvencija do 10 MHz
10 izlazna frekvencija do 2 MHz
11 izlazna frekvencija do 50 MHz

CNF – bitovi konfiguracije izlaza. Zavisi od načina rada:

Slažete se da će s ovom strukturom registra konfiguracije pinova, postavljanje svih bitova za konfiguraciju biti izuzetno nezgodno. Biće mnogo lakše to učiniti koristeći funkciju biblioteke GPIO_Init.
Nakon što inicijalizirate periferni modul, on se mora aktivirati pomoću funkcije PPP_Cmd:

PPP_Cmd(PPP, OMOGUĆI);

PPP_Cmd(PPP, OMOGUĆI);

Ova funkcija ne postoji za GPIO module; nakon inicijalizacije, možete odmah koristiti GPIO pinove. Mora se imati na umu da biblioteka pruža samo interfejs za hardver mikrokontrolera. Ako hardverski modul nema oznaku za aktivaciju/deaktivaciju, onda poziv funkcije PPP_Cmd(PPP, OMOGUĆI) nemoguće.
Za kontrolu stanja GPIOx pina u izlaznom modu i čitanje vrijednosti u ulaznom ili izlaznom načinu, biblioteka pruža sljedeće funkcije:

void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx); uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx);

void GPIO_SetBits (GPIO_TypeDef * GPIOx, uint16_t GPIO_Pin) ;

void GPIO_ResetBits (GPIO_TypeDef * GPIOx, uint16_t GPIO_Pin) ;

uint8_tGPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_tGPIO_Pin) ;

uint16_tGPIO_ReadOutputData(GPIO_TypeDef* GPIOx) ;

uint8_tGPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_tGPIO_Pin) ;

uint16_tGPIO_ReadInputData(GPIO_TypeDef* GPIOx) ;

Ostali periferni moduli su konfigurisani i rade na isti način. Međutim, postoje neke razlike zbog specifičnosti specifičnog hardverskog modula, pa vam toplo preporučujem da prvo pogledate primjere korištenja odabranog modula za STM32F10x SPL biblioteku.

Rukovanje prekidima i izuzecima

Cortex-M3 jezgro uključuje ugniježđeni vektorizirani kontroler prekida. Kontroler podržava do 240 izvora koji mogu uzrokovati prekide u jezgri procesora. Koliko vektora od 240 mogućih je implementirano u određeni model mikrokontrolera zavisi od proizvođača. Stm32f10x mikrokontroleri mogu imati do 43 ovakvih vektora.Ove prekidne linije nazivaju se maskiranim. Pored toga, postoji 15 Cortex-M3 vektora prekida jezgra i jedan eksterni nemaskiran EXTI prekid.
Kontroler podržava ugniježđene prekide, gdje se drugi prekid može pojaviti unutar jednog rukovaoca. U tom smislu, svaki izvor prekida ima svoj prioritet. Podržano je 16 nivoa prioriteta prekida.
Vektori prekida Cortex-M3 jezgre imaju najviše vrijednosti prioriteta.
Tri najviša nivoa prekida su dodijeljena vektorima i ne mogu se mijenjati:

Broj Handler Prioritet Opis
1 Reset_Handler -3 (najviše) Resetuj vektor
2 NMI_Handler -2 Prekid koji se ne može maskirati
3 HardFault_Handler -1 Hitni uslovi

Svim ostalim vektorima prekida mogu se dodijeliti nivoi prioriteta od 0 do 15.
Najviši nivo prioriteta odgovara nižoj vrijednosti. Nivo prioriteta se može dodijeliti ne samo pojedinačnom vektoru, već i cijeloj grupi vektora. Ova karakteristika olakšava rad sa velikim brojem vektora prekida.
Za postavljanje prioritetne grupe koristi se funkcija iz STM32F10x SPL biblioteke.

Zdravo svima. Kao što se sećate u prošlom članku, konfigurisali smo softverski paket za rad sa STM32 mikrokontrolerima i sastavili prvi program. U ovom postu ćemo se upoznati sa arhitekturom ove ploče, mikrokontrolerom i dostupnim bibliotekama za rad.

Ispod je slika ploče STM32F3 Discovery , gdje: 1 — MEMS senzor. L3GD20 3-osni digitalni žiroskop. 2 - MEMS sistem u kućištu koji sadrži 3-osni digitalni linearni akcelerometar i 3-osni digitalni geomagnetski senzor LSM303DLHC. 4 – LD1 (PWR) – 3.3V napajanje. 5 – LD2 – crvena/zelena LED. Zadana vrijednost je crvena. Zelena znači komunikaciju između ST-LINK/v2 (ili V2-B) i PC-a. Imam ST-LINK/v2-B, kao i indikaciju prilagođenog USB porta. 6. -LD3/10 (crvena), LD4/9 (plava), LD5/8 (narandžasta) i LD6/7 (zelena). U prošlom postu smo upalili LD4 LED. 7. – Dva dugmeta: korisnik USER i RESET. 8. - USB KORISNIK sa Mini-B konektorom.

9 - USB debuger/programator ST-LINK/V2. 1 0. - Mikrokontroler STM32F303VCT6. 11. — Eksterni visokofrekventni generator 8 MHz. 12. – Ovdje bi trebao biti niskofrekventni generator, nažalost nije zalemljen. 13. – SWD – interfejs. 14. – Džamperi za odabir programiranja eksternih ili internih kontrolera, u prvom slučaju moraju biti uklonjeni. 15 – Jumper JP3 – kratkospojnik dizajniran za povezivanje ampermetra za mjerenje potrošnje kontrolera. Jasno je da ako se izbriše, onda se naš kamen neće pokrenuti. 16. – STM32F103C8T6 na njemu se nalazi ploča za otklanjanje grešaka. 17. — LD3985M33R Regulator sa niskim padom napona i nivoom buke, 150mA, 3.3V.

Sada pogledajmo bliže arhitekturu mikrokontrolera STM32F303VCT6. Njegove tehničke karakteristike: kućište LQFP-100, jezgro ARM Cortex-M4, maksimalna frekvencija jezgre 72 MHz, kapacitet programske memorije 256 KB, tip programske memorije FLASH, kapacitet RAM-a SRAM 40 KB, RAM 8 KB, broj ulaza/izlaza 87, interfejsi ( CAN, I²C, IrDA, LIN, SPI, UART/USART, USB), periferije (DMA, I2S, POR, PWM, WDT), ADC/DAC 4*12 bit/2*12bit, napon napajanja 2 ... 3,6 V, radna temperatura –40...+85 C. Na slici ispod se nalazi pinout, gde vidimo 87 I/O portova, od kojih 45 Normalnih I/O (TC, TTa), 42 5-voltna tolerantna I /Os (FT, FTf) – kompatibilan sa 5 V (na ploči se nalaze 5V pinovi na desnoj strani, 3.3V na lijevoj). Svaka digitalna I/O linija može poslužiti kao opća I/O linija.
odredišnu ili alternativnu funkciju. Kako projekti budu napredovali, postepeno ćemo se upoznavati sa periferijom.

Razmotrite blok dijagram ispod. Srce je 32-bitna ARM Cortex-M4 jezgra koja radi do 72 MHz. Ima ugrađenu jedinicu FPU s pomičnim zarezom i jedinicu za zaštitu memorije MPU, ugrađene ćelije za praćenje makroa - Embedded Trace Macrocell (ETM), koje se mogu koristiti za praćenje izvršavanja glavnog programa unutar mikrokontrolera. Oni su u stanju da kontinuirano emituju ova zapažanja kroz ETM kontakte sve dok uređaj radi. NVIC (Nested vectored interrupt controller) – modul za kontrolu prekida. TPIU (Trace Port Interface Unit). Sadrži FLASH memoriju – 256 KB, SRAM 40 KB, RAM 8 KB. Između jezgre i memorije nalazi se Bus matrica, koja omogućava direktno povezivanje uređaja. Također ovdje vidimo dva tipa matričnih sabirnica AHB i APB, gdje je prva produktivnija i koristi se za komunikaciju internih komponenti velike brzine, a druga za periferne uređaje (ulazno/izlazne uređaje). Kontroler ima 4 12-bitna ADC (ADC) (5Mbit/s) i temperaturni senzor, 7 komparatora (GP Comparator1...7), 4 programabilna operaciona pojačala (OpAmp1...4) (PGA (Programmable Gain Array) ), 2 12-bitna DAC kanala (DAC), RTC (sat realnog vremena), dva watchdog tajmera - nezavisni i prozorski (WinWatchdog i Ind. WDG32K), 17 opće namjenskih i multifunkcionalnih tajmera.

Uopšteno govoreći, pogledali smo arhitekturu kontrolera. Sada pogledajte dostupne softverske biblioteke. Nakon što smo napravili pregled, možemo izdvojiti sljedeće: CMSIS, SPL i HAL. Pogledajmo svaki koristeći jednostavan primjer treptanja LED diode.

1). CMSIS(Cortex Microcontroller Software Interface Standard) - standardna biblioteka za Cortex®-M. Pruža podršku za uređaj i pojednostavljuje softverska sučelja. CMSIS pruža dosljedna i jednostavna sučelja za kernel, njegove periferije i operativne sisteme u realnom vremenu. Njegova upotreba je profesionalni način pisanja programa, jer... uključuje direktno upisivanje u registre i, shodno tome, neophodno je stalno čitanje i proučavanje listova podataka. Neovisno o proizvođaču hardvera.
CMSIS uključuje sljedeće komponente:
- CMSIS-CORE: Konzistentno pokretanje sistema i pristup periferiji;
- CMSIS-RTOS: Determinističko izvršavanje softvera u realnom vremenu (Determinističko izvršavanje softvera u realnom vremenu);
— CMSIS-DSP: Brza implementacija digitalne obrade signala;
- CMSIS-Driver: Generička periferna sučelja za međuopremu i kod aplikacije (Opšta periferna sučelja za međuopremu i kod aplikacije);
— CMSIS-Pack: Jednostavan pristup softverskim komponentama za višekratnu upotrebu (Jednostavan pristup softverskim komponentama za višekratnu upotrebu);
- CMSIS-SVD: Dosledan pogled na uređaj i periferne uređaje;
- CMSIS-DAP: Povezivanje sa jeftinim hardverom za evaluaciju. Softver za otklanjanje grešaka.

Na primjer, hajde da napišemo program - treperi LED dioda. Za to nam je potrebna dokumentacija koja opisuje registre. U mom slučaju RM0316 Referentni priručnik STM32F303xB/C/D/E, STM32F303x6/8, STM32F328x8, STM32F358xC, STM32F398xE napredni ARM® bazirani MCU-ovi, kao i opis specifične noge za koju je odgovoran DS9118: Cortex®-M4 32b MCU+FPU baziran na ARM®-u, do 256KB Flash+ 48KB SRAM, 4 ADC-a, 2 DAC kanala, 7 komp, 4 PGA, tajmeri, 2,0-3,6 V. Za početak ćemo taktirati port u programu, jer Standardno je sve onemogućeno, čime se postiže smanjena potrošnja energije. Otvorite Referentni priručnik i pogledajte odjeljak Reset i kontrola sata, zatim mapu registra RCC i pogledajte koji registar je odgovoran za omogućavanje IOPEEN-a

Pređimo na opis takta perifernih uređaja ovog registra AHB registar omogućavanja perifernog sata (RCC_AHBENR), gdje vidimo da je ovaj port ispod 21. bita. Uključite ga na RCC->AHBENR|=(1<<21) . Далее сконфигурируем регистры GPIO. Нас интересует три: GPIOE_MODER и GPIOx_ODR . C помощью них повторим программу с предыдущей статьи, затактируем PE8. Первый отвечает за конфигурацию входа выхода, выбираем 01: General purpose output mode. GPIOE->MODER|=0×10000 . Drugi je za uključivanje niskog/visokog nivoa na nozi. Ispod je program:

#include "stm32f3xx.h " //Datoteka zaglavlja mikrokontrolera
unsigned int i;
void delay() (
za (i=0;i<500000;i++);
}
int main (void) (
RCC->AHBENR|=(1<<21);
GPIOE->MODER|=0×10000;
dok (1)(
kašnjenje();
GPIOE->ODR|=0×100;
kašnjenje();
GPIOE->ODR&=~(0×100);
} }

2). SPL(Biblioteka standardnih perifernih uređaja)- ova biblioteka je namijenjena kombiniranju svih procesora iz ST Electronics-a. Dizajniran da poboljša prenosivost koda i prvenstveno je namijenjen programerima početnicima. ST radi na zamjeni za SPL pod nazivom "niski sloj" koja je kompatibilna sa HAL-om. Drajveri niskog sloja (LL) su dizajnirani da obezbede skoro lagan, stručno orijentisan sloj koji je bliži hardveru nego HAL. Pored HAL-a, dostupni su i LL API-ji. Primjer istog programa u SPL-u.

#include
#include
#include
#define LED GPIO_Pin_8
int main() (
long i;
GPIO_InitTypeDef gpio;
// Plava LED je spojena na port E, pin 8 (AHB sabirnica)
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOE, ENABLE);
// Konfigurirajte port E (LED)
GPIO_StructInit(&gpio); //deklariramo i inicijaliziramo varijablu strukture podataka
gpio.GPIO_Mode = GPIO_Mode_OUT;
gpio.GPIO_Pin = LED;
GPIO_Init(GPIOE, &gpio);
// Trepćuće LED diode
dok (1) (
// On
GPIO_SetBits(GPIOE, LED);
za (i = 0; i< 500000; i++);
// Sve isključeno
GPIO_ResetBits(GPIOE, LED);
za (i = 0; i< 500000; i++);
} }

Svaka funkcija je opisana u tehničkoj dokumentaciji UM1581 Korisnički priručnik Opis STM32F30xx/31xx Standardne periferne biblioteke. Ovdje povezujemo tri zaglavlja koja sadrže potrebne podatke, strukture, funkcije kontrole resetiranja i sinhronizacije, kao i za konfiguriranje ulazno/izlaznih portova.

3). HAL- (Hardverski pristupni nivo, sloj hardverske apstrakcije)- Još jedna zajednička biblioteka za razvoj. Uz to je izašao i program CubeMX za konfiguraciju koju smo koristili u prošlom članku. Tamo smo također napisali program za treptanje LED-a koristeći ovu biblioteku. Kao što vidimo na slici ispod, kocka generiše HAL i CMSIS drajvere. Pa, hajde da opišemo glavne datoteke koje se koriste:
- system_stm32f3x.c i system_stm32f3x.h- obezbediti minimalne skupove funkcija za konfigurisanje sistema za merenje vremena;
— core_cm4.h – omogućava pristup registrima jezgre i njegovih perifernih uređaja;
- stm32f3x.h - datoteka zaglavlja mikrokontrolera;
— startup_system32f3x.s — startup kod, sadrži tabelu vektora prekida, itd.

#include "main.h"
#include "stm32f3xx_hal.h"
void SystemClock_Config(void); /*Objavite funkcije konfiguracije sata*/
statička void MX_GPIO_Init(void); /*Inicijaliziraj I/O*/
int main (void) (
/*Resetovanje svih perifernih uređaja, inicijalizira Flash interfejs i Systick.*/
HAL_Init();
/* Konfigurišite sistemski sat */
SystemClock_Config();
/* Inicijaliziranje svih konfiguriranih perifernih uređaja */
MX_GPIO_Init();
dok (1) (
HAL_GPIO_TogglePin(GPIOE, GPIO_PIN_8); //Promeni stanje noge
HAL_Delay(100); )
}
void SystemClock_Config (void){
RCC_OscInitTypeDef RCC_OscInitStruct;
RCC_ClkInitTypeDef RCC_ClkInitStruct;

RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = 16;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
if (HAL_RCC_OscConfig (&RCC_OscInitStruct) != HAL_OK){

}
/**Inicijalizira taktove CPU, AHB i APB magistrale */
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig (&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK){
_Error_Handler(__FILE__, __LINE__);
}
/**Konfigurišite Systick vrijeme prekida*/
HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
/**Konfigurišite Systick */
HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
/* SysTick_IRQn konfiguracija prekida */
HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
}
/** Konfigurišite pinove kao analogni ulaz i izlaz EVENT_OUT EXTI */
static void MX_GPIO_Init (void){
GPIO_InitTypeDef GPIO_InitStruct;
/* Omogući sat GPIO portova */
__HAL_RCC_GPIOE_CLK_ENABLE();
/*Konfigurišite izlazni nivo GPIO pina */
HAL_GPIO_WritePin (GPIOE, GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11
|GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15, GPIO_PIN_RESET);
/*Konfigurišite GPIO pinove: PE8 PE9 PE10 PE11 PE12 PE13 PE14 PE15 */
GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11
|GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed ​​= GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
}
void _Error_Handler (char * fajl, int linija){
dok (1) (
} }
#ifdef USE_FULL_ASSERT

Void assert_failed (uint8_t* datoteka, uint32_t linija){
}
#endif
Ovdje, baš kao iu prethodnom primjeru, možemo vidjeti opis svake funkcije u dokumentaciji, na primjer UM1786 Korisnički priručnik Opis STM32F3 HAL i drajvera niskog sloja.

Možemo rezimirati da je prva opcija, korištenjem CMSIS-a, manje glomazna. Za svaku biblioteku postoji dokumentacija. U narednim projektima koristićemo HAL i CMSIS koristeći konfiguracioni program STCube i, ako je moguće, direktno koristiti registre, bez softverskih omotača. Zaustavimo se tamo danas. U sljedećem članku ćemo pogledati osnovne principe izgradnje pametne kuće. Ćao svima.