Kako postaviti pametne telefone i računala. Informativni portal
  • Dom
  • OS
  • STM32F407 (STM32F4-DISCOVERY) - Nestandardni pristup - Standardna knjižnica dio 1.

STM32F407 (STM32F4-DISCOVERY) - Nestandardni pristup - Standardna knjižnica dio 1.

Još jednom želim pisati o jednostavnom početku sa STM32, samo ovaj put bez korištenja nečijih predložaka ili primjera - s objašnjenjem svakog koraka. Članci će sadržavati kontinuirano numeriranje koraka.

1. Instalirajte IAR

Izgradnja projekta u IAR-u

1. Pretprocesor

  1. uklanja komentare

2. Prevoditelj

3. Linker

3. Napravite novi projekt u IAR-u

Nakon pokretanja IAR-a pojavljuje se prozor informacijskog centra koji nam nije potreban. Kliknite na izbornik Projekt -> Stvori novi projekt. Odaberite alatni lanac: ARM (malo je vjerojatno da ćete imati nešto drugo na tom popisu), Projektni predlošci: C -> main.

U lijevom prozoru ("Radni prostor") desnom tipkom miša kliknite izbornik i stvorite novu grupu (Dodaj ->

Desnom tipkom miša kliknite CMSIS

U grupu Pokretanje

Završili smo s CMSIS-om.

U grupu StdPeriphLib

U grupu Korisnik

5. Postavljanje projekta

  1. Opće opcije -> Cilj ->
Odaberite ST -> STM32F100 -> ST STM32F100xB. Ovo je naš kontrolor. 2. Opće opcije -> Konfiguracija knjižnice -> CMSIS: potvrdite okvir Koristi CMSIS. Ovo će koristiti biblioteku CMSIS ugrađenu u kompajler. Od verzije 6.30 IAR se počeo isporučivati ​​s ugrađenim CMSIS-om, što se čini boljim - ali je donijelo neku zbrku sa starim projektima. 3. C / C ++ prevodilac ->
$ PROJ_DIR $ \

* Debugger -> Setup -> Driver: odaberite ST – Link, budući da je ovo programator ugrađen u Discovery ploču. Sada postavljamo sam programator: * Debugger -> ST – LINK -> Interface: odaberite SWD (programator na ploči je spojen na kontroler preko SWD-a, ne JTAG). * Program za ispravljanje pogrešaka ->
#include "stm32f10x_conf.h" 

void main ()
{
dok (1)
{
}
}

<1000000; i++);


za (i = 0; i<1000000; i++);

#include "stm32f10x_conf.h"

void main ()
{





int i;
dok (1)
{

za (i = 0; i<1000000; i++);

<1000000; i++); } }

arhivu s projektom GPIO. Na sreću, ovaj projekt možete spremiti i od sada ga koristiti kao predložak tako da ne morate ponovno konfigurirati cijeli projekt. Cijeli ciklus: 1. I/O portovi (/index.php/stm32-from_zero_to_rtos-2_timers/ "STM32 - od nule do RTOS. 2: Tajmer i prekidi") (/index.php/stm32-from_zero_to_rtos-3_timer_outputs/ " STM32 - od nule do RTOS-a. 3: Timer izlazi") [Još jednom želim pisati o jednostavnom početku od STM32, samo ovaj put bez korištenja nečijih predložaka ili primjera - s objašnjenjem svakog koraka. Članci će sadržavati kontinuirano numeriranje koraka.

0. Nabavite STM32VLDiscovery ploču

Kupujemo u trgovini, košta 600 rubalja. Morat ćete instalirati upravljačke programe na ploču - mislim da to neće uzrokovati poteškoće.

1. Instalirajte IAR

Radit ćemo u IAR-u - dobrom IDE-u s izvrsnim kompajlerom. Nedostaje mu praktičnost pisanja koda - ali za naše potrebe to je dovoljno. Koristim IAR verziju 6.50.3, znate gdje se može nabaviti.

2. Preuzmite perifernu knjižnicu

Nisam pobornik rada s registrima u fazi učenja. Stoga predlažem da preuzmete ST perifernu biblioteku kako biste dobili prikladne funkcije pristupa svim potrebnim postavkama.

Napravite mapu "STM32_Projects", stavite mapu Libraries tamo iz preuzete arhive (stsw-stm32078.zip/an3268/stm32vldiscovery_package), sadrži CMSIS (biblioteku iz ARM-a za sve Cortex mikrokontrolere, opis i adrese svih resursa) i STM3S2tFrd10. knjižnica ST sa svim funkcijama.

Tu također stvaramo mapu „1. GPIO“, koji će sadržavati naš prvi projekt.

Stablo mapa prikazano je na slici. Učinite to, jer će tada relativne staze u ovom stablu biti vrlo važne.

Pa, da bismo razumjeli o čemu govorimo - preuzmite dokument od 1100 stranica za ove kontrolere.

Izgradnja projekta u IAR-u

Potrebno je jasno razumjeti bit procesa montaže projekta. Radi praktičnosti, podijelimo ga u faze.

1. Pretprocesor

Predprocesor prolazi kroz sve .c datoteke projekta (i main.c i sve datoteke u radnom prostoru). Radi sljedeće:

  1. uklanja komentare
  2. proširuje direktive #include, zamjenjujući ih sadržajem navedene datoteke. Ovaj proces se izvodi rekurzivno, počevši od .c-datoteke i unoseći svaki #include .h na koji se naiđe, a ako .h-datoteka također sadrži #include direktive, predprocesor će ih također unijeti. Ispada takvo stablo uključuje. Imajte na umu: ne rješava situaciju dvostrukih uključivanja, tj. ista .h datoteka može biti uključena nekoliko puta ako je #include na nekoliko mjesta u projektu. Ovu situaciju treba riješiti s definicijama.
  3. vrši zamjene makroa - proširuje makronaredbe
  4. prikuplja direktive prevoditelja.

Predprocesor generira .i datoteke, koje su vrlo zgodne za pronalaženje pogrešaka građenja - makar samo zato što u potpunosti proširuju sve makronaredbe. Spremanje ovih datoteka može se omogućiti u postavkama projekta.

U ovom trenutku, graditelj ima sve .c datoteke u projektu spremne za kompilaciju kao .i datoteke. Još nema poveznica između datoteka.

2. Prevoditelj

Nakon prolaska kroz pretprocesor, prevodilac optimizira i kompilira svaku .i-datoteku, proizvodeći binarni kod. Ovdje trebate odrediti vrstu procesora, dostupnu memoriju, programski jezik, razinu optimizacije i slične stvari.

Što prevodilac radi kada naiđe na poziv funkcije u nekoj .c datoteci koja nije opisana u ovoj datoteci? On to traži u naslovima. Ako zaglavlja kažu da je funkcija u drugoj .c-datoteci, jednostavno ostavlja pokazivač na ovu drugu datoteku na ovom mjestu.

U ovom trenutku, graditelj ima sve .c datoteke projekta prevedene u .o datoteke. Zovu se kompilirani moduli. Sada postoje veze između datoteka u obliku pokazivača na mjestima gdje se pozivaju "strane" funkcije - ali to je još uvijek nekoliko različitih datoteka.

3. Linker

Gotovo sve je spremno, samo trebate provjeriti sve veze između datoteka - proći kroz main.o i zamijeniti prevedene module umjesto pokazivača na funkcije drugih ljudi. Ako se neka funkcija iz knjižnica ne koristi, ona se ili neće uopće prevesti u prethodnoj fazi, ili je neće nigdje zamijeniti linker (ovisno o načinu rada sakupljača). U svakom slučaju, neće ući u gotovi binarni kod.

Povezivač također može izvesti neke završne radnje s binarnim, na primjer, izračunati njegov kontrolni zbroj.

Prvi projekt - rad s I/O portovima

3. Napravite novi projekt u IAR-u

Nakon pokretanja IAR-a pojavljuje se prozor informacijskog centra koji nam nije potreban. Kliknite na izbornik Projekt -> Stvori novi projekt. Odaberite alatni lanac: ARM (malo je vjerojatno da ćete imati nešto drugo na tom popisu), Projektni predlošci: C -> main.

Sada imate novi prazan C projekt i datoteku main.c.

4. Povezujemo se s projektom knjižnice

U lijevom prozoru ("Radni prostor") desnom tipkom miša kliknite izbornik i stvorite novu grupu (Dodaj -> Dodaj grupu), nazovite je CMSIS. Kreirajmo grupe StdPeriphLib, Startup i User na isti način. Sada dodajemo datoteke u grupe (podcrtat ću sve datoteke kako bih ih lakše pratio).

Desnom tipkom miša kliknite CMSIS, Dodaj, Dodaj datoteke - idite na Biblioteke / CMSIS / CM3, iz mape DeviceSupport / ST / STM32F10x (podrška za kristale) uzimamo system_stm32f10x.c (ovo je opis periferije određene postavke kristala i sata). U mapi CoreSupport (podrška za kernel) nalazi se i core_cm3.c (ovo je opis Cortex M3 jezgre), ali ga nećemo uzeti - jer je već u kompajleru. O ovome ću dalje pisati.

U grupu Pokretanje dodajte datoteku startup_stm32f10x_md_vl.s iz mape Libraries / CMSIS / CM3 / DeviceSupport / ST / STM32F10x / startup / iar. Ovo su radnje koje treba izvršiti pri pokretanju. Ovo je gotovo u potpunosti postavka rukovatelja za razne prekide (sami rukovatelji će biti malo dalje). Još uvijek postoje datoteke za druge kristale, ali nas zanima točno md_vl - to znači srednja gustoća (prosječna veličina memorije, postoje i kristali s malim i velikim volumenima), linija vrijednosti (procjena linija - kristal STM32F100 namijenjen je samo za procjenu sposobnosti i prelazak na sljedeće obitelji).

Završili smo s CMSIS-om.

U grupu StdPeriphLib dodajte datoteke stm32f10x_rcc.c i stm32f10x_gpio.c iz mape Libraries / STM32F10x_StdPeriph_Driver / src. Prva je funkcija rada sa sustavom takta, a druga je rad s I / O pinama.

U grupu Korisnik povucite i ispustite naš glavni.c. Nije potrebno, ali je ljepše.

Stablo GPIO projekta sada izgleda ovako:

Radni prostor je spreman, nećemo mu ništa više dodavati.

Ostaje samo staviti još jednu datoteku u mapu projekta, koja povezuje zaglavlja sa svim datotekama periferne biblioteke. Možete ga sami napisati, ali lakše je uzeti gotovu. Idemo na stsw-stm32078.zip/an3268/stm32vldiscovery_package/Project/Examples/GPIOToggle - tamo uzimamo datoteku stm32f10x_conf.h (konfiguracija projekta) i stavljamo je u “1. GPIO". Ovo je jedina gotova datoteka koju uzimamo.

stm32f10x_conf.h je samo dump potrebnih modula i funkcija assert. Ova će se funkcija pozvati u slučaju pogrešaka u radu s funkcijama periferne biblioteke: na primjer, staviti nešto smeća u funkciju GPIO_WriteBit umjesto GPIOC - ukratko, ST je izvanredno reosiguran. U ovoj funkciji možete jednostavno pokrenuti beskonačnu petlju - while (1); Još uvijek moramo ući u stm32f10x_conf.h - komentirati redove uključivanja datoteka nepotrebnih perifernih uređaja, ostavljajući samo stm32f10x_rcc.h, stm32f10x_gpio.h i misc.h - kako bismo to mogli sami napisati.

5. Postavljanje projekta

Desnom tipkom miša kliknite naziv projekta u prozoru Workspace:

  1. Opće opcije -> Cilj -> Varijanta procesora: odaberite "Uređaj", pritisnite tipku s desne strane
Odaberite ST -> STM32F100 -> ST STM32F100xB. Ovo je naš kontrolor. 2. Opće opcije -> Konfiguracija knjižnice -> CMSIS: potvrdite okvir Koristi CMSIS. Ovo će koristiti biblioteku CMSIS ugrađenu u kompajler. Od verzije 6.30 IAR se počeo isporučivati ​​s ugrađenim CMSIS-om, što se čini boljim - ali je donijelo neku zbrku sa starim projektima. 3. Prevoditelj C / C ++ -> Preprocesor. Ovdje pišemo staze do mapa knjižnice:
$ PROJ_DIR $ \
$ PROJ_DIR $ \ .. \ Biblioteke \ CMSIS \ CM3 \ DeviceSupport \ ST \ STM32F10x
$ PROJ_DIR $ \ .. \ Biblioteke \ STM32F10x_StdPeriph_Driver \ inc
$ PROJ_DIR $ makronaredba znači trenutnu mapu (projektna mapa), a .. - ide jednu razinu više. Registrirali smo putove do mape s kristalnim opisom, kao i do datoteka zaglavlja periferne biblioteke, budući da sve .c datoteke u projektu imaju svoja zaglavlja, a prevodilac mora znati gdje ih tražiti. Također ovdje trebate napisati USE \ _STDPERIPH \ _DRIVER u Definiranim simbolima. Ovo će povezati potrebne konfiguracijske datoteke (poput spomenutog stm32f10x_conf.h) s projektom. Dakle, kartica Preprocesor će izgledati ovako: * Debugger -> Setup -> Driver: odaberite ST – Link, budući da je ovo programator ugrađen u Discovery ploču. Sada postavljamo sam programator: * Debugger -> ST – LINK -> Interface: odaberite SWD (programator na ploči je spojen na kontroler preko SWD-a, ne JTAG). * Debugger -> Preuzimanje: stavite kvačicu Koristi flash loader(e), "Popuni firmver u flash memoriju". Logično je, bez toga se ništa neće popuniti.## 6. Pisanje koda I prvo ću napisati što će ovaj kod učiniti. Pokazat će jednostavnu stvar, treptanje LED-a (PC8 na ploči Discovery) sa pauzom u beskonačnoj petlji. Uključujemo datoteku zaglavlja konfiguracije projekta, stm32f10x \ _conf.h. U njemu nalazimo redak #include "stm32f10x \ _exti.h" - ovo je redak 35 i komentiramo ga s dvije kose crte. Činjenica je da našem projektu nije potreban EXTI modul. Datoteka main.c već sadrži int main funkciju, a njezina jedina radnja je povratak 0. Izbrišemo ovaj redak (nećemo vratiti nikakve vrijednosti), promijenimo tip funkcije u void (iz istog razloga) i pišemo beskonačna petlja:
#include "stm32f10x_conf.h" 

void main ()
{
dok (1)
{
}
}

### Pokretanje GPIO modula I/O portovi u STM32 nazivaju se GPIO - Opće namjene Ulaz/Izlaz. Stoga smo uključili biblioteku stm32f10x_gpio.c. Međutim, ovo nije sve što nam treba, malo teorije: svi periferni uređaji na čipu onemogućeni su prema zadanim postavkama, kako iz napajanja tako i iz frekvencije takta. Da biste ga uključili, morate poslati signal sata. Ovim upravlja RCC modul, a datoteka stm32f10x_rcc.c postoji za rad s njim. GPIO modul visi na sabirnici APB2. Tu su i AHB (analog sabirnice procesor-sjeverni most) i APB1 (kao i APB2 - analog sabirnice sjeverni most-južni most). Stoga, prvo što trebamo učiniti je omogućiti taktiranje GPIOC modula. Ovo je modul odgovoran za PORTC; tu su i GPIOA, GPIOB i tako dalje. To se radi ovako: RCC \ _APB2PeriphClockCmd (RCC \ _APB2Periph_GPIOC, ENABLE); Jednostavno je - zovemo funkciju opskrbe taktnim signalom s APB2 sabirnice na GPIOC modul i time omogućujemo ovaj modul. Naravno, to radimo na samom početku void main funkcije. Ovdje su samo osnove potrebne za razumijevanje. Također imam puno više [detaljniji članak o GPIO modulu] (/index.php / stm32-% e2% 86% 92-% d0% bf% d0% be% d1% 80% d1% 82% d1% 8b- gpio / "STM32 → GPIO portovi"). ### Konfiguriranje GPIOC modula Ostalo je vrlo malo, morate konfigurirati GPIOC modul. Nogu postavljamo na izlaz (postoje i ulazne i alternativne funkcije), podešavamo oštrinu rubova (u svrhu EM kompatibilnosti), izlazni drajver (push-pull ili open source). To radimo odmah nakon inicijalizacije porta. GPIO \ _InitTypeDef GPIO \ _InitStructure; GPIO \ _InitStructure.GPIO \ _Speed ​​= GPIO \ _Speed ​​\ _2MHz; GPIO \ _InitStructure.GPIO \ _Mode = GPIO \ _Mode \ _Out_PP; GPIO \ _InitStructure.GPIO \ _Pin = GPIO \ _Pin \ _8; GPIO \ _Init (GPIOC, & GPIO \ _InitStructure); Eto, to je to, nakon toga PC8 noga će raditi kao push-pull izlaz s relativno glatkim rubovima (maksimalna frekvencija prebacivanja je 2 MHz. Oštri rubovi su 50 MHz). Glatkost prednjih strana okom nećemo primijetiti, ali se to može vidjeti na osciloskopu. ### Uključite LED Pozovite funkciju GPIO \ _WriteBit (GPIOC, GPIO \ _Pin \ _8, Bit \ _SET); LED će se upaliti. ### Uključi/isključi u petlji U petlji while (1) pišemo kod kako bismo ga uključili, pauzirali, isključili i zatim ponovno pauzirali:

GPIO_WriteBit (GPIOC, GPIO_Pin_8, Bit_SET);  za (i = 0; i<1000000; i++);

GPIO_WriteBit (GPIOC, GPIO_Pin_8, Bit_RESET);
za (i = 0; i<1000000; i++);

Dakle, cijela main.c datoteka izgleda ovako:

#include "stm32f10x_conf.h"

void main ()
{
RCC_APB2PeriphClockCmd (RCC_APB2Periph_GPIOC, ENABLE);

GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Speed ​​= GPIO_Speed_2MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
GPIO_Init (GPIOC, & GPIO_InitStructure);

GPIO_WriteBit (GPIOC, GPIO_Pin_8, Bit_SET);

int i;
dok (1)
{
GPIO_WriteBit (GPIOC, GPIO_Pin_8, Bit_SET);
za (i = 0; i<1000000; i++);

GPIO_WriteBit (GPIOC, GPIO_Pin_8, Bit_RESET); za (i = 0; i<1000000; i++); } }

## 7. Pokrenimo! STM32VLDiscovery ploču povezujemo s računalom putem microUSB-a, pritisnemo gumb Download and Debug u IAR-u. Program se ulijeva u mikrokontroler (možete vidjeti prozor s trakom napretka koji se brzo zatvara - veličina programa je tako mala) i počinje otklanjanje pogrešaka. IAR se zaustavlja na prvoj instrukciji koda (ovo je prilično zgodno za otklanjanje pogrešaka), morate ga pokrenuti tipkom Go. Sve bi trebalo raditi - plava PC8 LED na ploči STM32VLDiscovery bi trebala. Kao i uvijek, možete preuzeti arhivu s GPIO projektom. Srećom, možete spremiti ovaj projekt i koristiti ga kao predložak od sada pa nadalje tako da ne morate ponovno konfigurirati cijeli projekt. Cijeli ciklus: 1. I/O portovi (/index.php/stm32-from_zero_to_rtos-2_timers/ "STM32 - od nule do RTOS. 2: Tajmer i prekidi") (/index.php/stm32-from_zero_to_rtos-3_timer_outputs/ " STM32 - od nule do RTOS-a. 3: Timer izlazi ")

] (/ index.php / stm32-from_zero_to_rtos-4_exti_nvic / “STM32 - od nule do RTOS. 4: Vanjski prekidi i NVIC”) 5. Instalirajte FreeRTOS

Dakle, već smo se digli na noge, u smislu da je sve što nam treba spojeno na izlaze mikrokontrolera na STM32VL Discovery ploči, naučili smo govoriti, u programskom jeziku C, vrijeme bi bilo da kreiramo projekt u prvom razredu.

Pisanje programa

Kada završite sa stvaranjem i postavljanjem svog projekta, možete početi pisati pravi program. Kao što je uobičajeno za sve programere, prvi program napisan za rad na računalu je program koji prikazuje natpis "HelloWorld", a za sve mikrokontrolere prvi program za mikrokontroler treperi LED. Nećemo biti iznimka od ove tradicije i napisat ćemo program koji će kontrolirati LD3 LED na STM32VL Discovery ploči.

Nakon kreiranja praznog projekta u IAR-u, generira minimalni programski kod:

Sada će se naš program uvijek "vrtjeti" u petlji dok.

Da bismo mogli kontrolirati LED, moramo omogućiti taktiranje porta na koji je spojen i konfigurirati odgovarajući pin porta mikrokontrolera za izlaz. Kao što smo ranije raspravljali u prvom dijelu, za dopuštanje taktiranja porta S bit odgovara IOPCEN Registar RCC_APB2ENR... Prema dokumentu “ RM0041Referencapriručnik.pdf"Da bi se omogućilo taktiranje sabirnice luka S potrebno u registru RCC_APB2ENR postavite bit IOPCEN po jedinici. Tako da kada je ovaj bit postavljen, ne resetujemo ostale postavljene u ovom registru, moramo primijeniti operaciju logičkog zbrajanja (logičko "ILI") na trenutno stanje registra i zatim upisati rezultirajuću vrijednost u sadržaj registar. U skladu sa strukturom ST knjižnice, pristup vrijednosti registra za čitanje i upisivanje u nju se vrši preko pokazivača na strukturu RCC-> APB2 ENR... Dakle, prisjećajući se materijala iz drugog dijela, možete napisati sljedeći kod koji postavlja bit IOPCEN u registru RCC_APB2ENR:

Kao što možete vidjeti iz datoteke "stm32f10x.h", vrijednost bita IOPCEN definiran kao 0x00000010, što odgovara četvrtom bitu ( IOPCEN) Registar APB2ENR i odgovara vrijednosti navedenoj u podatkovnoj tablici.

Sada konfigurirajmo izlaz na isti način. 9 luka S... Da bismo to učinili, moramo konfigurirati ovaj pin porta za izlaz u push-pull modu. Registar je odgovoran za postavljanje načina rada ulaza/izlaza GPIOC_CRH, već smo ga razmotrili u, njegov opis je također u odjeljku "7.2.2 Visoki registar konfiguracije porta" u podatkovnoj tablici. Za konfiguriranje izlaza na izlazni način s maksimalnom brzinom od 2 MHz potrebno je u registru GPIOC_CRH instalirati NAČIN 9 na jedan i resetirajte bit NAČIN 9 na nulu. Bitovi su odgovorni za postavljanje načina rada izlaza kao glavne funkcije s push-pull izlazom. CNF9 i CNF9 , da bi se konfigurirao traženi način rada, oba ova bita moraju biti izbrisana na nulu.

Sada je pin porta na koji je LED spojen postavljen na izlaz, da bismo kontrolirali LED, moramo promijeniti stanje pina porta postavljanjem izlaza na logički. Postoje dva načina da promijenite stanje pina porta, prvi je da izravno upišete u registar statusa porta promijenjeni sadržaj registra porta, baš kao što smo učinili postavku porta. Ova metoda se ne preporučuje zbog mogućnosti situacije u kojoj se u registar portova može upisati netočna vrijednost. Ova situacija može nastati ako se tijekom promjene stanja registra, od trenutka kada je stanje registra već pročitano i do trenutka kada se promijenjeno stanje upiše u registar, promijeni bilo koji periferni uređaj ili prekid. stanje ove luke. Po završetku operacije promjene stanja registra, vrijednost će biti upisana u registar bez uzimanja u obzir promjena koje su se dogodile. Iako je vjerojatnost da će se ova situacija dogoditi vrlo mala, ipak vrijedi koristiti drugu metodu u kojoj je opisana situacija isključena. Za to postoje dva registra u mikrokontroleru GPIOx_BSRR i GPIOx_BRR... Prilikom upisivanja logičke jedinice u traženi bit registra GPIOx_BRR odgovarajući pin porta bit će resetiran na logičku nulu. Registar GPIOx_BSRR može postaviti i resetirati stanje pinova porta, da bi se pin porta postavio na logičku jedinicu, potrebno je postaviti bitove BSn, koji odgovara broju traženog bita, ti se bitovi nalaze u nižim registrima bajta. Za resetiranje stanja izlaza porta na logičku nulu, potrebno je upisati bitove BRn odgovarajućih pinova, ovi bitovi se nalaze u bitovima višeg reda registra porta.

LD3 LED je spojen na pin 9 luka S... Da bismo uključili ovu LED diodu, moramo primijeniti logičku jedinicu na odgovarajući pin porta kako bismo "upalili" LED.

Dodajmo kod za postavljanje izlaza LED porta u naš program, a također dodamo i softversku funkciju odgode za smanjenje frekvencije prebacivanja LED-a:

// Ne zaboravite povezati datoteku zaglavlja s opisom registara mikrokontrolera

#include "stm32f10x.h"

poništiti Kašnjenje ( poništiti);

poništiti Kašnjenje ( poništiti)
{
nepotpisano dugo ja;
za(i = 0; i<2000000; i++);
}

// Naša glavna funkcija

poništiti glavni ( poništiti)
{


RCC-> APB2ENR | = RCC_APB2ENR_IOPCEN;

// obrišite MODE9 bitove (resetirajte bite MODE9_1 i MODE9_0 na nulu)
GPIOC-> CRH & = ~ GPIO_CRH_MODE9;

// Postavite bit MODE9_1 da konfigurirate izlaz na izlaz brzinom od 2MHz
GPIOC-> CRH | = GPIO_CRH_MODE9_1;

// očisti CNF bitove (konfiguriraj kao izlaz opće namjene, uravnotežen (push-pull))
GPIOC-> CRH & = ~ GPIO_CRH_CNF9;

dok(1)
{

// Postavite pin 9 priključka C na logičku jedinicu (LED je uključen)
GPIOC-> BSRR = GPIO_BSRR_BS9;


Odgoda ();


GPIOC-> BSRR = GPIO_BSRR_BR9;


Odgoda ();

}
}

Arhivu s izvornim kodom programa napisanog izravnom kontrolom registara mikrokontrolera možete preuzeti slijedeći poveznicu.

Naš prvi radni program je napisan, prilikom pisanja, za rad i konfiguraciju perifernih uređaja, koristili smo podatke iz službene tablice s podacima " RM0041Referencapriručnik.pdf", Ovaj izvor informacija o registrima mikrokontrolera je najtočniji, ali da biste ga koristili morate ponovno pročitati puno informacija, što komplicira pisanje programa. Kako bi se olakšao proces konfiguriranja perifernih uređaja mikrokontrolera, postoje različiti generatori koda, program Microxplorer predstavljen je kao službeni uslužni program tvrtke ST, ali još uvijek nije vrlo funkcionalan i iz tog razloga su programeri treće strane kreirali alternativni program „STM32 Generator programskog koda » ... Ovaj program vam omogućuje da jednostavno dobijete periferni konfiguracijski kod pomoću prikladnog, intuitivnog grafičkog sučelja (vidi sliku 2).


Riža. 2 Snimka zaslona programa za generiranje koda STM32

Kao što možete vidjeti na slici 2, kod za podešavanje LED izlaza koji je generirao program podudara se s kodom koji smo ranije napisali.

Za pokretanje napisanog programa, nakon kompajliranja izvornog koda, potrebno je učitati naš program u mikrokontroler i vidjeti kako se izvršava.

Videozapis načina za otklanjanje pogrešaka programa koji treperi LED dioda

Video programa koji treperi LED dioda na STM32VL Discovery ploči

Funkcije knjižnice za rad s perifernim uređajima

Za pojednostavljenje rada s postavljanjem registara periferije mikrokontrolera, tvrtka ST razvila je knjižnice zahvaljujući čijoj upotrebi nije potrebno toliko temeljito čitati podatkovnu tablicu, budući da se pri korištenju ovih knjižnica rad na pisanju program će postati bliži pisanju programa visoke razine, budući da se sve funkcije niske razine implementiraju na razini knjižničnih funkcija. Međutim, ne treba u potpunosti napustiti korištenje izravnog rada s registrima mikrokontrolera, s obzirom na činjenicu da funkcije knjižnice zahtijevaju više procesorskog vremena za svoje izvršavanje, zbog čega njihova upotreba u vremenski kritičnim dijelovima programa nije opravdano. Ali ipak, u većini slučajeva, stvari poput inicijalizacije periferije nisu kritične za vrijeme izvođenja, a prednost se daje upotrebljivosti knjižničnih funkcija.

Sada napišimo naš program koristeći ST biblioteku. Program treba konfigurirati ulazne / izlazne portove, da biste koristili funkcije knjižnice za konfiguriranje portova, morate spojiti datoteku zaglavlja " stm32f10x_gpio.h"(Vidi tablicu 1). Ova datoteka se može povezati uklanjanjem komentara odgovarajućeg retka u uključenoj konfiguracijskoj datoteci zaglavlja " stm32f10x_conf.h". Na kraju datoteke " stm32f10x_gpio.h»Postoji popis deklaracija funkcija za rad s portovima. Detaljan opis svih dostupnih funkcija nalazi se u datoteci " stm32f10x_stdperiph_lib_um.chm», Kratak opis najčešće korištenih dat je u tablici 2.

Tablica 2: Opis osnovnih funkcija konfiguracije porta

Funkcija

Opis funkcije, proslijeđenih i vraćenih parametara

GPIO_DeInit (
GPIO_TypeDef * GPIOx)

Postavlja vrijednosti registara postavki GPIOx porta na njihove zadane vrijednosti

GPIO_Init (
GPIO_TypeDef * GPIOx,

Instalira registre postavki GPIOx porta u skladu s navedenim parametrima u strukturi GPIO_InitStruct

GPIO_StructInit (
GPIO_InitTypeDef * GPIO_InitStruct)

Ispunjava sva polja strukture GPIO_InitStruct zadanim vrijednostima

uint8_t GPIO_ReadInputDataBit (
GPIO_TypeDef * GPIOx,
uint16_t GPIO_Pin);

Pročitajte ulaznu vrijednost GPIO_Pin porta GPIOx

uint16_t GPIO_ReadInputData (
GPIO_TypeDef * GPIOx)

Čitanje ulaznih vrijednosti svih pinova GPIOx porta

GPIO_SetBits (
GPIO_TypeDef * GPIOx,
uint16_t GPIO_Pin)

Postavljanje izlazne vrijednosti GPIO_Pin pina GPIOx porta na logičku jedinicu

GPIO_ResetBits (
GPIO_TypeDef * GPIOx,
uint16_t GPIO_Pin)

Resetirajte izlaznu vrijednost GPIO_Pin pina GPIOx porta na logičku nulu

GPIO_WriteBit (
GPIO_TypeDef * GPIOx,
uint16_t GPIO_Pin,
BitAction BitVal)

Zapisivanje BitVal vrijednosti na GPIO_Pin pin GPIOx porta

GPIO_Write (
GPIO_TypeDef * GPIOx,
uint16_t PortVal)

Zapisivanje vrijednosti PortVal u GPIOx port

Kao što možete vidjeti iz opisa funkcija, kao parametri postavki porta, itd., funkciji se ne prosljeđuje mnogo različitih pojedinačnih parametara, već jedna struktura. Strukture su kombinirani podaci koji imaju neki logički odnos. Za razliku od nizova, strukture mogu sadržavati podatke različitih tipova. Drugim riječima, struktura je skup različitih varijabli s različitim tipovima kombiniranih u jednu vrstu varijable. Varijable u ovoj strukturi nazivaju se polja strukture, a pristupa im se na sljedeći način, prvo se upisuje naziv strukture, zatim točka i naziv polja strukture (naziv varijable u ovoj strukturi) napisano.

Popis varijabli uključenih u strukture za funkcije rada s portovima opisan je u istoj datoteci malo iznad opisa funkcija. Tako, na primjer, struktura " GPIO_InitTypeDef"Ima sljedeću strukturu:

typedef struktura
{

uint16_t GPIO_Pin; /*!< Specifies the GPIO pins to be configured.
Ovaj parametar može biti bilo koja vrijednost @ref GPIO_pins_define * /

GPIOSpeed_TypeDef GPIO_Speed; /*!< Specifies the speed for the selected pins.
Ovaj parametar može biti vrijednost @ref GPIOSpeed_TypeDef * /

GPIOMode_TypeDef GPIO_Mode; /*!< Specifies the operating mode for the selected pins.
Ovaj parametar može biti vrijednost @ref GPIOMode_TypeDef * /

) GPIO_InitTypeDef;

Prvo polje ove strukture sadrži varijablu " GPIO_ Pin"Tip nepotpisan kratak, u ovu varijablu je potrebno upisati zastavice brojeva odgovarajućih pinova, za koje treba izvršiti potrebna podešavanja. Možete konfigurirati nekoliko pinova odjednom postavljanjem nekoliko konstanti kao parametra pomoću operatora bitno ILI(cm.). Bitwise OR će sve one "pokupiti" od navedenih konstanti, a same konstante su maska ​​upravo namijenjena takvoj upotrebi. Makro definicije konstanti navedene su u istoj datoteci ispod.

Drugo polje strukture " GPIO_InitTypeDef"Postavlja najveću moguću izlaznu brzinu porta. Gore je naveden popis mogućih vrijednosti za ovo polje:

Opis mogućih vrijednosti:

  • GPIO_Mode_AIN- analogni ulaz (engleski Analog INput);
  • GPIO_Mode_IN_FLOATING- unos bez povlačenja, viseći (engleski Input float) u zraku
  • GPIO_Mode_IPD- Input Pull-down
  • GPIO_Mode_IPU- Input Pull-up
  • GPIO_Mode_Out_OD- Izlazni otvoreni odvod
  • GPIO_Mode_Out_PP- izlaz u dva stanja (engleski Output Push-Pull - naprijed i natrag)
  • GPIO_Mode_AF_OD- otvoreni izlaz za odvod za alternativne funkcije. Koristi se u slučajevima kada bi pin trebao biti kontroliran od strane perifernih uređaja spojenih na ovaj pin porta (na primjer, Tx USART1 pin, itd.)
  • GPIO_Mode_AF_PP- isto, ali s dvije države

Slično, možete vidjeti strukturu varijabli drugih struktura potrebnih za rad s funkcijama knjižnice.

Za rad sa strukturama, baš kao i varijablama, morate deklarirati i dodijeliti im jedinstveno ime, nakon čega se možete pozivati ​​na polja deklarirane strukture prema imenu koje joj je dodijeljeno.

// Deklarirajte strukturu

/*
Prije početka popunjavanja polja strukture, preporuča se inicijalizirati sadržaj strukture zadanim podacima, to je učinjeno kako bi se spriječilo upisivanje netočnih podataka ako iz nekog razloga nisu popunjena sva polja strukture.

Da biste proslijedili vrijednosti strukture funkciji, morate staviti simbol & ispred naziva strukture. Ovaj simbol govori prevoditelju da je potrebno proći u funkciju ne vrijednosti sadržane u samoj strukturi, već memorijsku adresu na kojoj se te vrijednosti nalaze. To je učinjeno kako bi se smanjio broj potrebnih radnji procesora za kopiranje sadržaja strukture, a također vam omogućuje spremanje RAM-a. Dakle, umjesto prosljeđivanja skupa bajtova sadržanih u strukturi funkciji, samo će jedan biti prebačen s adresom strukture.
*/

/ * Upišite u polje GPIO_Pin strukture GPIO_Init_struct broj pina porta, koji ćemo dalje konfigurirati * /

GPIO_Init_struct.GPIO_Pin = GPIO_Pin_9;

/ * Slično, ispunite polje GPIO_Speed ​​* /

/*
Nakon što smo ispunili potrebna polja strukture, ova struktura mora biti proslijeđena funkciji koja će izvršiti potreban unos u odgovarajuće registre. Uz strukturu s postavkama ove funkcije potrebno je pronijeti i naziv porta za koji su postavke namijenjene.
*/

Gotovo svi periferni uređaji konfigurirani su na približno isti način, razlike su samo u parametrima i naredbama specifičnim za svaki uređaj.

Sada napišimo naš LED treptajući program koristeći samo funkcije knjižnice.

// Ne zaboravite povezati datoteku zaglavlja s opisom registara mikrokontrolera

#include "stm32f10x.h"
#include "stm32f10x_conf.h"

// deklarirati funkciju odgode programa

poništiti Kašnjenje ( poništiti);

// sama funkcija odgode programa

poništiti Kašnjenje ( poništiti)
{
nepotpisano dugo ja;
za(i = 0; i<2000000; i++);
}

// Naša glavna funkcija

poništiti glavni ( poništiti)
{

// Omogući priključak C sabirnice sata
RCC_APB2PeriphClockCmd (RCC_APB2Periph_GPIOC, ENABLE);

// Deklarirajte strukturu za konfiguriranje porta
GPIO_InitTypeDef GPIO_Init_struct;

// Ispuni strukturu početnim vrijednostima
GPIO_StructInit (& GPIO_Init_struct);

/ * Upišite u polje GPIO_Pin strukture GPIO_Init_struct broj pina porta, koji ćemo dalje konfigurirati * /
GPIO_Init_struct.GPIO_Pin = GPIO_Pin_9;

// Slično, ispunite polja GPIO_Speed ​​i GPIO_Mode
GPIO_Init_struct.GPIO_Speed ​​= GPIO_Speed_2MHz;
GPIO_Init_struct.GPIO_Mode = GPIO_Mode_Out_PP;

// Proslijedite popunjenu strukturu za izvođenje radnji za postavljanje registara
GPIO_Init (GPIOC, & GPIO_Init_struct);

// Naša glavna beskonačna petlja
dok(1)
{
// Postavite pin 9 priključka C na logičku jedinicu (LED je uključen)
GPIO_SetBits (GPIOC, GPIO_Pin_9);

// Dodajte softversko odgodu kako bi LED dioda bio uključen neko vrijeme
Odgoda ();

// Resetirajte stanje pina 9 priključka C na logičku nulu
GPIO_ResetBits (GPIOC, GPIO_Pin_9);

// Ponovno dodajte softversko kašnjenje
Odgoda ();
}
}

veza.

Iz gornjeg primjera može se vidjeti da korištenje funkcija knjižnice za rad s perifernim uređajima omogućuje približavanje pisanja programa za mikrokontroler objektno orijentiranom programiranju, a također smanjuje potrebu za čestim pristupom podatkovnoj tablici za čitanje opisa registri mikrokontrolera, ali korištenje knjižničnih funkcija zahtijeva više znanje programskog jezika... S obzirom na to, za ljude koji nisu posebno upoznati s programiranjem, jednostavnija opcija za pisanje programa bit će način pisanja programa bez korištenja knjižničnih funkcija, s izravnim pristupom registrima mikrokontrolera. Za one koji dobro poznaju programski jezik, ali su slabo upućeni u mikrokontrolere, posebice STM32, korištenje bibliotečkih funkcija uvelike pojednostavljuje proces pisanja programa.

Ova okolnost, kao i činjenica da je ST vodio računa o visokom stupnju kompatibilnosti, kako hardverske tako i softverske, svojih različitih mikrokontrolera, pridonosi njihovom lakšem proučavanju, jer nije potrebno upuštati se u strukturne značajke raznih kontrolera serije STM32 i omogućuje vam da odaberete bilo koji od mikrokontrolera dostupnih u STM32 liniji kao mikrokontroler za proučavanje.

Rukovalac prekida

Mikrokontroleri imaju jednu izvanrednu sposobnost - da zaustave izvršavanje glavnog programa u određenom događaju i nastave izvršavati poseban potprogram - rukovalac prekida... Izvori prekida mogu biti i vanjski događaji - prekidi za primanje / prijenos podataka kroz bilo koje sučelje za prijenos podataka, ili promjena izlaznog stanja, i interni - prekoračenje tajmera itd. Popis mogućih izvora prekida za STM32 mikrokontrolere dat je u podatkovnoj tablici " RM0041 Referentni priručnik"U poglavlju" 8 Prekidi i događaji».

Budući da je rukovatelj prekida također funkcija, bit će napisan kao redovna funkcija, ali da bi prevodilac znao da je ova funkcija rukovalac za određeni prekid, kao naziv funkcije treba odabrati unaprijed definirana imena kojoj naznačena su preusmjeravanja vektora prekida. Popis naziva ovih funkcija s kratkim opisom može se pronaći u datoteci asemblera " startup_stm32f10x_md_vl.s". Jedan rukovalac prekida može imati nekoliko izvora prekida, na primjer, funkciju rukovatelja prekidom " USART1_IRQHandler"Može se pozvati u slučaju kraja prijema i kraja prijenosa bajta, itd.

Da biste počeli raditi s prekidima, morate konfigurirati i inicijalizirati NVIC kontroler prekida. U arhitekturi Cortex M3, svakom se prekidu može dodijeliti vlastita prioritetna grupa za slučajeve kada se nekoliko prekida dogodi istovremeno. Zatim biste trebali konfigurirati izvor prekida.

Polje NVIC_IRQChannel označava koji prekid želimo konfigurirati. Konstanta USART1_IRQn označava kanal odgovoran za prekide povezane s USART1. Definiran je u datoteci " stm32f10x.h", Tu su također definirane i druge slične konstante.

Sljedeća dva polja označavaju prioritet prekida (maksimalne vrijednosti ova dva parametra određuje odabrana prioritetna grupa). Posljednje polje zapravo omogućuje korištenje prekida.

U funkciju NVIC_Init, kao i pri postavljanju portova, prosljeđuje se pokazivač na strukturu za primjenu napravljenih postavki i zapisivanje u odgovarajuće registre mikrokontrolera.

Sada, u postavkama modula, trebate postaviti parametre za koje će ovaj modul generirati prekid. Prvo morate uključiti prekid, to se radi pozivom funkcije Ime_ITConfig () koji se nalazi u datoteci zaglavlja periferije.

// Omogući prekide na kraju prijenosa bajtova na USART1
USART_ITConfig (USART1, USART_IT_TXE, ENABLE);

// Omogući prekide na kraju primanja bajta od strane USART1
USART_ITConfig (USART1, USART_IT_RXNE, ENABLE);

Opis parametara proslijeđenih funkciji može se pronaći u datoteci izvornog koda perifernog uređaja, neposredno iznad lokacije same funkcije. Ova funkcija omogućuje ili onemogućuje prekide za različite događaje iz navedenog perifernog modula. Kada se ova funkcija izvrši, mikrokontroler će moći generirati prekide za događaje koji su nam potrebni.

Nakon što uđemo u funkciju rukovanja prekidom, moramo provjeriti iz kojeg je događaja došlo do prekida, a zatim obrisati napetu zastavicu, inače će mikrokontroler po izlasku iz prekida odlučiti da nismo obrađivali prekid, jer je zastavica prekida još uvijek je postavljena.

Mikrokontroleri s Cortex-M3 jezgrom imaju namjenski sistemski mjerač vremena za izvođenje različitih, malih radnji koje se ponavljaju s preciznim razdobljem. Funkcije ovog mjerača vremena uključuju samo poziv prekida u strogo određenim vremenskim intervalima. Obično se u prekidu koji poziva ovaj mjerač vremena postavlja kod za mjerenje trajanja različitih procesa. Deklaracija funkcije za postavljanje timera nalazi se u datoteci " jezgra_ cm3. h". Argument proslijeđen funkciji je broj otkucaja sistemske sabirnice između intervala kada se poziva rukovatelj prekida sistemskog tajmera.

SysTick_Config (clk);

Sada kada smo se pozabavili prekidima, ponovno ćemo napisati naš program koristeći sistemski mjerač vremena kao element za postavljanje vremena. Od mjerača vremena" SysTick"Jesu li sustavni i mogu ga koristiti različiti funkcionalni blokovi našeg programa, bilo bi razumno premjestiti funkciju rukovanja prekidom iz sistemskog timera u zasebnu datoteku, iz ove funkcije u pozivanje funkcija za svaki funkcionalni blok posebno.

Primjer datoteke "main.c" programa za treptanje LED-a pomoću prekida:

// Povežite datoteku zaglavlja s opisom registara mikrokontrolera

#include "stm32f10x.h"
#include "stm32f10x_conf.h"
#include "main.h"

unsigned int LED_timer;

// Funkcija pozvana iz funkcije rukovatelja prekidom tajmera sustava

poništiti SysTick_Timer_main ( poništiti)
{
// Ako varijabla LED_timer još nije dosegla 0,
ako(LED_timer)
{
// Provjerite njegovu vrijednost, ako je veća od 1500, upalite LED
ako(LED_timer> 1500) GPIOC-> BSRR = GPIO_BSRR_BS9;

// inače, ako je manje od ili jednako 1500, onda se isključi
drugo GPIOC-> BSRR = GPIO_BSRR_BR9;

// Smanjenje varijable LED_timer
LED_timer--;
}

// Ako vrijednost varijable dosegne nulu, postavite novu vrijednost na 2000
drugo LED_timer = 2000;
}

// Naša glavna funkcija

poništiti glavni ( poništiti)
{

// Omogući priključak C sabirnice sata
RCC_APB2PeriphClockCmd (RCC_APB2Periph_GPIOC, ENABLE);

// Deklarirajte strukturu za konfiguriranje porta
GPIO_InitTypeDef GPIO_Init_struct;

// Ispuni strukturu početnim vrijednostima
GPIO_StructInit (& GPIO_Init_struct);

/ * Upišite u polje GPIO_Pin strukture GPIO_Init_struct broj pina porta, koji ćemo dalje konfigurirati * /
GPIO_Init_struct.GPIO_Pin = GPIO_Pin_9;

// Slično, ispunite polja GPIO_Speed ​​i GPIO_Mode
GPIO_Init_struct.GPIO_Speed ​​= GPIO_Speed_2MHz;
GPIO_Init_struct.GPIO_Mode = GPIO_Mode_Out_PP;

// Proslijedite popunjenu strukturu za izvođenje radnji za postavljanje registara
GPIO_Init (GPIOC, & GPIO_Init_struct);

// odabir prioritetne grupe za prekide
NVIC_PriorityGroupConfig (NVIC_PriorityGroup_0);

// Konfigurirajte rad tajmera sustava s intervalom od 1 ms
SysTick_Config (24000000/1000);

// Naša glavna beskonačna petlja
dok(1)
{
// Ovaj put je prazan, sva LED kontrola se odvija u prekidima
}
}

Dio izvornog koda u datoteci "stm32f10x_it.c":


#include "main.h"

/**
* @brief Ova funkcija obrađuje SysTick Handler.
* @param Ništa
* @retval Nema
*/

poništiti SysTick_Handler ( poništiti)
{
SysTick_Timer_main ();
}

Primjer radnog nacrta LED programa koji treperi pomoću prekida može se preuzeti s poveznice.

Ovim završavam svoju priču o osnovama razvoja programa za STM32 mikrokontroler. Dao sam sve informacije koje su vam potrebne da biste mogli dalje samostalno proučavati STM32 mikrokontrolere. Priloženi materijal je samo početna točka, budući da se potpuni opis rada s mikrokontrolerima ne može opisati ni u jednom članku. Osim toga, proučavanje mikrokontrolera bez stjecanja praktičnog iskustva je nemoguće, a pravo iskustvo dolazi postupno tijekom godina rada, eksperimenata, s gomilanjem raznih softverskih i hardverskih razvoja, kao i čitanjem raznih članaka i dokumentacije o mikrokontrolerima. No, neka vas to ne plaši, jer su informacije navedene u članku sasvim dovoljne da napravite svoj prvi uređaj na mikrokontroleru, a daljnje znanje i iskustvo možete steći sami, razvijajući svaki put sve složenije i bolje uređaje. i poboljšati svoje vještine.

Nadam se da bih vas mogao zainteresirati za proučavanje mikrokontrolera i razvoj uređaja na njima, a moji radovi će vam biti korisni i zanimljivi.

Prilikom izrade svoje prve aplikacije na STM32 mikrokontroleru, postoji nekoliko načina. Prvi, klasični, uzimamo točan opis kontrolera na web stranici www.st.com, koji se pojavljuje pod nazivom "Referentni priručnik" i čitamo opis perifernih registara. Zatim ih pokušavamo zapisati i vidjeti kako periferne jedinice rade. Čitanje ovog dokumenta vrlo je korisno, ali u prvoj fazi svladavanja mikrokontrolera, možete to odbiti, čudno. STMicroelectronics inženjeri su napisali biblioteku upravljačkih programa za standardne periferije. Štoviše, napisali su mnoge primjere korištenja ovih drajvera, koji mogu svesti programiranje vaše aplikacije na pritiskanje tipki Ctrl + C i Ctrl + V, nakon čega slijedi mala izmjena primjera korištenja drajvera prema vašim potrebama. Stoga je povezivanje biblioteke perifernih upravljačkih programa s vašim projektom druga metoda izgradnje aplikacije. Osim brzine pisanja, postoje i druge prednosti ove metode: univerzalnost koda i korištenje drugih vlasničkih knjižnica kao što su USB, Ethernet, kontrola pogona itd., koje su date u izvornom kodu i pomoću standardni periferni drajver. Postoje i nedostaci ove metode: Gdje se možete snaći s jednom linijom koda, standardni upravljački program periferije STM32 će napisati 10. Sama biblioteka periferije također je dostupna u obliku izvornih datoteka, tako da možete pratiti koji dio registrirati promjene određene funkcije. Ako želite, možete prijeći s druge metode pisanja programa na prvu komentirajući dio koda koji samostalno koristi standardnu ​​biblioteku, koja izravno kontrolira periferni registar. Kao rezultat ove akcije, dobit ćete u brzini kontrole, količini RAM-a i ROM-a, a izgubiti u univerzalnosti koda. U svakom slučaju, inženjeri tvrtke Promelectronica preporučuju korištenje knjižnice standardnih perifernih uređaja barem u prvoj fazi.

Najveće poteškoće očekuju razvojnog programera pri povezivanju knjižnice sa svojim projektom. Ako ne znate kako to učiniti, možete potrošiti puno vremena na ovaj događaj, što je u suprotnosti sa samom idejom korištenja gotovog drajvera. Materijal je posvećen povezivanju standardne biblioteke s bilo kojom obitelji STM32.

Svaka obitelj STM32 ima svoju standardnu ​​perifernu biblioteku. To je zbog činjenice da je sama periferija drugačija. Na primjer, periferija STM32L kontrolera ima funkciju štednje energije kao jedan od zadataka, što podrazumijeva dodavanje upravljačkih funkcija. Klasični primjer može se smatrati ADC-om, koji u STM32L ima mogućnost isključivanja hardvera, u nedostatku naredbe za pretvorbu dulje vrijeme - jedna od posljedica zadatka za uštedu energije. ADC kontrolera obitelji STM32F nemaju ovu funkciju. Zapravo, zbog hardverske razlike na periferiji, imamo različite biblioteke drajvera. Osim očite razlike u funkcijama kontrolera, dolazi do poboljšanja na periferiji. Dakle, periferni uređaji kontrolora obitelji koji su kasnije objavljeni mogu biti promišljeniji i praktičniji. Na primjer, periferni uređaji STM32F1 i STM32F2 kontrolera imaju razlike u upravljanju. Po mišljenju autora, upravljanje periferijama STM32F2 je praktičnije. I to je razumljivo zašto: obitelj STM32F2 objavljena je kasnije i to je omogućilo programerima da uzmu u obzir neke od nijansi. Sukladno tome, za ove obitelji - individualne periferne kontrolne knjižnice. Ideja iza gore navedenog je jednostavna: na stranici mikrokontrolera koji ćete koristiti nalazi se odgovarajuća periferna biblioteka za njega.

Unatoč razlici u periferiji u obiteljima, vozači kriju 90% razlika u sebi. Na primjer, gore spomenuta funkcija ugađanja ADC-a izgleda isto za sve obitelji:

void ADC_Init (ADC_Nom, ADC_Param),

gdje je ADC_Nom broj ADC-a u obliku ADC1, ADC2, ADC3, itd.

ADC_Param - pokazivač na strukturu podataka, kako ADC treba biti konfiguriran (od čega početi, koliko kanala digitalizirati, treba li to izvoditi ciklički, itd.)

10% razlika između obitelji, u ovom primjeru, koje će se morati ispraviti pri prelasku iz jedne STM32 obitelji u drugu, skriveno je u ADC_Param strukturi. Broj polja u ovoj strukturi može varirati ovisno o obitelji. Opći dio ima istu sintaksu. Dakle, prijevod aplikacije za jednu STM32 obitelj, napisanu na temelju standardnih perifernih biblioteka u drugu, prilično je jednostavan. Što se tiče univerzalizacije rješenja na mikrokontrolerima, STMicroelectronics je neodoljiva!

Dakle, preuzeli smo biblioteku za korišteni STM32. Što je sljedeće? Zatim moramo stvoriti projekt i povezati potrebne datoteke s njim. Razmotrimo stvaranje projekta koristeći razvojno okruženje IAR Embedded Workbench kao primjer. Pokrećemo razvojno okruženje i idemo na karticu "Projekt", odabiremo stavku "Kreiraj projekt" za izradu projekta:

U novom projektu koji se pojavi unesite postavke tako da zadržite pokazivač iznad naziva projekta, pritisnete desnu tipku miša i odaberete "Opcije" u padajućem izborniku:

RAM i ROM memorijska područja:

Kada kliknete gumb "Spremi", okolina će ponuditi pisanje nove datoteke opisa kontrolera u mapu projekta. Autor preporučuje stvaranje pojedinačne * .icp datoteke za svaki projekt i pohranjivanje u mapu projekta.

Ako ćete otklanjati pogreške u svom projektu u krugu, što je preporučljivo, tada unosimo vrstu debuggera koji ćemo koristiti:

Na kartici odabranog debuggera označavamo sučelje za povezivanje debuggera (u našem slučaju je odabran ST-Link) na kontroler:



Od sada je naš projekt bez knjižnica spreman za kompajliranje i učitavanje u kontroler. U drugim okruženjima kao što su Keil uVision4, Resonance Ride7 itd., morat ćete učiniti isto.

Ako upišete redak u datoteku main.c:

#include "stm32f10x.h" ili

#include "stm32f2xx.h" ili

#include "stm32f4xx.h" ili

#include "stm32l15x.h" ili

#include "stm32l10x.h" ili

#include "stm32f05x.h"

navodeći lokaciju ove datoteke ili kopirajući ovu datoteku u mapu projekta, tada će neka memorijska područja biti povezana s perifernim registrima odgovarajuće obitelji. Sama datoteka nalazi se u mapi standardne periferne biblioteke u odjeljku: \ CMSIS \ CM3 \ DeviceSupport \ ST \ STM32F10x (ili sličan naziv za druge obitelji). Od sada, adresu perifernog registra kao broj zamjenjujete njenim imenom. Čak i ako ne namjeravate koristiti funkcije standardne biblioteke, preporuča se napraviti takvu vezu.

Ako ćete koristiti prekide u svom projektu, preporuča se povezati početnu datoteku s nastavkom * .s, koja se nalazi duž putanje \ CMSIS \ CM3 \ DeviceSupport \ ST \ STM32F10x \ startup \ iar ili slično za druge obitelji. Važno je napomenuti da je datoteka različita za svako okruženje. U skladu s tim, ako koristimo IAR EWB, tada moramo uzeti datoteku iz mape IAR. To je zbog malo drugačije sintakse okruženja. Stoga, kako bi projekt odmah krenuo, STMicroelectronics inženjeri napisali su nekoliko opcija za pokretanje datoteka za nekoliko najpopularnijih razvojnih okruženja. Većina obitelji STM32 ima jednu datoteku. Obitelj STM32F1 ima nekoliko datoteka za pokretanje:

  • startup_stm32f10x_cl.s - za STM32F105 / 107 mikrokontrolere
  • startup_stm32f10x_xl.s - za STM32F101 / STM32F103 mikrokontrolere 768 kb i više
  • startup_stm32f10x_hd.s - za STM32F101 / STM32F103 mikrokontrolere s 256-512 kb Flash memorije
  • startup_stm32f10x_md.s - za STM32F101 / STM32F102 / STM32F103 mikrokontrolere sa 64-128 kb Flash memorije
  • startup_stm32f10x_ld.s - za STM32F101 / STM32F102 / STM32F103 mikrokontrolere s Flash memorijom manjom od 64 kb
  • startup_stm32f10x_hd_vl.s za mikrokontrolere STM32F100 s 256-512 kb flash memorije
  • startup_stm32f10x_md_vl.s za mikrokontrolere STM32F100 sa 64-128 kb Flash memorije
  • startup_stm32f10x_ld_vl.s za mikrokontrolere STM32F100 s 32 KB Flash memorije ili manje

Dakle, ovisno o obitelji, podobitelji i razvojnom okruženju, dodajte datoteku za pokretanje projektu:

Ovdje se ispostavlja da je mikrokontroler kada se program pokrene. Prekid sekvencijalno poziva funkciju SystemInit (), a zatim __iar_program_start. Druga funkcija nula ili upisuje unaprijed definirane vrijednosti globalnih varijabli, nakon čega se prebacuje na glavni () korisnički program. Funkcija SystemInit () podešava sat mikrokontrolera. Ona je ta koja daje odgovore na pitanja:

  • Trebam li prijeći na vanjski kvarc (HSE)?
  • Kako pomnožiti frekvenciju iz HSI / HSE?
  • Trebate li povezati red za preuzimanje naredbi?
  • Koliko je kašnjenja potrebno pri učitavanju naredbe (zbog male brzine Flash memorije)
  • Kako podijeliti taktiranje perifernih sabirnica?
  • Trebate li kod staviti u vanjski RAM?

Funkcija SystemInit () može se ručno napisati u vašem projektu. Ako ovu funkciju uredite kao praznu, tada će kontroler raditi na internom RC oscilatoru s frekvencijom od oko 8 MHz (ovisno o vrsti obitelji). Opcija 2 - povežite datoteku system_stm32f10x.c s projektom (ili sličnog imena, ovisno o vrsti korištene obitelji), koja se nalazi u biblioteci duž puta: Libraries \ CMSIS \ CM3 \ DeviceSupport \ ST \ STM32F10x. Ova datoteka sadrži funkciju SystemInit (). Obratite pažnju na frekvenciju vanjskog kristala HSE_VALUE. Ovaj je parametar postavljen u datoteci zaglavlja stm32f10x.h. Standardna vrijednost je 8 i 25MHz, ovisno o obitelji STM32. Glavni zadatak funkcije SystemInit () je prebaciti taktiranje na vanjski kristal i pomnožiti ovu frekvenciju na određeni način. Što se događa ako je vrijednost HSE_VALUE navedena kao 8MHz, jezgra mora imati takt od 72MHz, ali u stvari postoji kristal od 16MHz na ploči? Kao rezultat takvih netočnih radnji, jezgra će dobiti takt od 144 MHz, što može biti iznad zajamčenog rada sustava na STM32. Oni. kada povezujete datoteku system_stm32f10x.c, morat ćete navesti vrijednost HSE_VALUE. Sve to znači da datoteke system_stm32f10x.c, system_stm32f10x.h i stm32f10x.h (ili slične po imenu za druge obitelji) moraju biti individualne za svaki projekt. I

STMicroelectronics inženjeri stvorili su alat za konfiguraciju sata koji vam omogućuje ispravnu konfiguraciju takta sustava. Ovo je Excel datoteka koja generira datoteku system_stm32xxx.c (sličnu po imenu za danu obitelj obitelji) nakon navođenja ulaznih i izlaznih parametara sustava. Pogledajmo kako to radi koristeći obitelj STM32F4 kao primjer.

Opcije su interni RC oscilator, unutarnji RC oscilator s množenjem frekvencije ili vanjski kristal s množenjem frekvencije. Nakon odabira izvora takta, unesite parametre željene konfiguracije sustava, kao što su ulazna frekvencija (kada koristite vanjski kristal), frekvencija takta jezgre, djelitelj frekvencije takta periferne sabirnice, rad međuspremnika za dohvaćanje naredbi i ostalo . Klikom na gumb "Generiraj" dobivamo prozor


Povezivanje datoteke system_stm32f4xx.c i njezinih analoga zahtijevat će povezivanje još jedne datoteke standardne periferne biblioteke. Za upravljanje satom postoji cijeli skup funkcija koje se pozivaju iz datoteke system_stm32xxxxxx.c. Te se funkcije nalaze u datoteci stm32f10x_rcc.c i njenom zaglavlju. Sukladno tome, kada povezujete datoteku system_stm32xxxxxx.c s projektom, morate spojiti stm32f10x_rcc.c, inače će povezivač okruženja prijaviti odsutnost opisa funkcija s imenom RCC_xxxxxxx. Navedena datoteka nalazi se u perifernoj biblioteci pod stazom: Libraries \ STM32F10x_StdPeriph_Driver \ src, i njeno zaglavlje \ Libraries \ STM32F10x_StdPeriph_Driver \ inc.

Datoteke zaglavlja perifernog drajvera povezane su u datoteci stm32f10x_conf.h, na koju upućuje stm32f10x.h. Datoteka stm32f10x_conf.h jednostavno je skup datoteka zaglavlja za specifične upravljačke programe periferije kontrolera koji će biti uključeni u projekt. U početku su sva zaglavlja "#include" označena kao komentari. Povezivanje datoteke zaglavlja periferije sastoji se od uklanjanja komentara iz odgovarajućeg naziva datoteke. U našem slučaju, ovo je redak #include "stm32f10x_rcc.h". Očito je da je datoteka stm32f10x_conf.h individualna za svaki projekt, budući da različiti projekti koriste različite periferne uređaje.

I posljednja stvar. Potrebno je navesti nekoliko direktiva za predprocesor kompajlera i putove do datoteka zaglavlja.



Putovi do datoteka zaglavlja mogu biti različiti, ovisno o lokaciji periferne biblioteke u odnosu na mapu projekta, ali prisutnost "USE_STDPERIPH_DRIVER" je obavezna pri povezivanju perifernih upravljačkih programa standardne biblioteke.

Dakle, standardnu ​​biblioteku smo povezali s projektom. Štoviše, na projekt smo spojili jedan od standardnih perifernih drajvera koji kontrolira sat sustava.

Saznali smo kako struktura knjižnice izgleda iznutra, a sada par riječi o tome kako izgleda izvana.



Dakle, povezivanje datoteke zaglavlja stm32f10x.h u aplikaciji podrazumijeva povezivanje drugih datoteka zaglavlja i kodnih datoteka. Neki od prikazanih na slici su gore opisani. Nekoliko riječi o ostalom. Datoteke STM32F10x_PPP.x su datoteke upravljačkog programa periferije. Primjer povezivanja takve datoteke prikazan je gore, ovo je RCC - periferni uređaji za upravljanje satom sustava. Ako želimo spojiti drajvere drugih perifernih uređaja, tada se naziv povezanih datoteka dobiva zamjenom "PPP" s nazivom periferije, na primjer, ADC - STM32F10x_ADC.s, ili I/O portovi STM32F10x_GPIO.s, ili DAC - STM32F10x_DAC.s. Općenito, intuitivno je jasno koju datoteku treba spojiti prilikom povezivanja određene periferije. Datoteke "misc.c", "misc.h" su u osnovi iste STM32F10x_PPP.x, samo što kontroliraju kernel. Na primjer, postavljanje vektora prekida, koji je ugrađen u kernel, ili upravljanje SysTick timerom, koji je dio jezgre. Datoteke xxxxxxx_it.c opisuju vektore nemaskiranih prekida kontrolera. Mogu se nadopuniti perifernim vektorima prekida. Datoteka core_m3.h opisuje jezgru CortexM3. Ova jezgra je standardizirana i može se naći u mikrokontrolerima drugih proizvođača. Za univerzalizaciju na više platformi, STMicroelectronics je radio na stvaranju zasebne knjižnice CortexM jezgre, nakon čega ju je ARM standardizirao i proširio na druge proizvođače mikrokontrolera. Tako će prijelaz na STM32 s kontrolera drugih proizvođača s CortexM jezgrom biti malo lakši.

Dakle, standardnu ​​perifernu biblioteku možemo povezati s bilo kojom obitelji STM32. Oni koji su to naučili dobit će nagradu: vrlo jednostavno programiranje mikrokontrolera. Knjižnica, osim upravljačkih programa u obliku izvornih datoteka, sadrži mnoge primjere korištenja perifernih uređaja. Na primjer, razmislite o stvaranju projekta koji uključuje izlaze za usporedbu vremena. Tradicionalnim pristupom pomno ćemo proučiti opis registara ove periferije. Ali sada možemo proučiti tekst programa za trčanje. Idemo u mapu s primjerima standardnih perifernih uređaja, koja se nalazi duž putanje ProjectSTM32F10x_StdPeriph_Examples. Ovdje ćete pronaći primjere mapa s nazivima korištenih perifernih uređaja. Idemo u mapu "TIM". Tajmeri u STM32 imaju mnogo funkcija i postavki, pa je nemoguće demonstrirati s jednim primjerom mogućnosti kontrolera. Stoga, unutar navedenog imenika postoji mnogo primjera korištenja mjerača vremena. Zanima nas generiranje PWM signala pomoću timera. Idemo u mapu "7PWM_Output". Unutar se nalazi opis programa na engleskom i skup datoteka:

main.c stm32f10x_conf.h stm32f10x_it.h stm32f10x_it.c system_stm32f10x.c

Ako projekt nema prekida, tada se sadržaj u potpunosti nalazi u datoteci main.c. Te datoteke kopiramo u direktorij projekta. Nakon što smo sastavili projekt, dobit ćemo program za STM32 koji će konfigurirati timer i I/O portove za generiranje 7 PWM signala iz timera 1. Zatim možemo prilagoditi već napisani kod za naš zadatak. Na primjer, smanjite broj PWM signala, promijenite radni ciklus, smjer brojanja itd. Funkcije i njihovi parametri dobro su opisani u datoteci stm32f10x_stdperiph_lib_um.chm. Nazivi funkcija i njihovi parametri lako se povezuju s njihovom namjenom za one koji malo znaju engleski. Radi jasnoće predstavljamo dio koda uzetog primjera:

/ * Konfiguracija vremenske baze * / TIM_TimeBaseStructure.TIM_Prescaler = 0; // nema prethodnog dodjeljivanja impulsa za brojanje (16-bitni registar) TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; // smjer odbrojavanja prema gore TIM_TimeBaseStructure.TIM_Period = TimerPeriod; // broji do vrijednosti TimerPeriod (konstanta u programu) TIM_TimeBaseStructure.TIM_ClockDivision = 0; // nema brojanja unaprijed dodjele TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; // brojač prekoračenja za generiranje događaja (ne koristi se u programu) TIM_TimeBaseInit (TIM1, & TIM_TimeBaseStructure); // unos vrijednosti TimeBaseStructure u registre timera 1 (unos podataka u ovu // varijablu je iznad) / * Konfiguracija kanala 1, 2, 3 i 4 u PWM modu * / // postavljanje PWM izlaza TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; // PWM2 način rada TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; // omogućimo izlaz signala PWM timera TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable; // omogućiti besplatni izlaz PWM timera TIM_OCInitStructure.TIM_Pulse = Channel1Pulse; // širina impulsa Channel1Pulse - konstanta u programu TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; // postavljanje izlaznog polariteta TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High; // postavljanje polariteta komplementarnog izlaza TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set; // postavlja sigurno stanje PWM izlaza TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset; // postavlja sigurno stanje komplementarnog PWM izlaza TIM_OC1Init (TIM1, & TIM_OCInitStructure); // unesite vrijednosti varijable TIM_OCInitStructure u PWM registre kanala 1 // timer1 TIM_OCInitStructure.TIM_Pulse = Channel2Pulse; // mijenjamo širinu impulsa u varijabli OCInitStructure i unosimo je u TIM_OC2Init (TIM1, & TIM_OCInitStructure); // PWM registri kanala 2 timer1 TIM_OCInitStructure.TIM_Pulse = Channel3Pulse; // mijenjamo širinu impulsa u varijabli OCInitStructure i unosimo je u TIM_OC3Init (TIM1, & TIM_OCInitStructure); // PWM registri kanala 3 timer1 TIM_OCInitStructure.TIM_Pulse = Channel4Pulse; // mijenjamo širinu impulsa u varijabli OCInitStructure i unosimo je u TIM_OC4Init (TIM1, & TIM_OCInitStructure); // registrira PWM kanal 4 timer1 / * Omogućavanje brojača TIM1 * / TIM_Cmd (TIM1, ENABLE); // start timer1 / * Omogući glavni izlaz TIM1 * / TIM_CtrlPWMO izlazi (TIM1, ENABLE); // omogući usporedbu izlaza timera 1

Na desnoj strani, autor je ostavio komentar na ruskom jeziku za svaki redak programa. Ako otvorite isti primjer u opisu funkcija biblioteka stm32f10x_stdperiph_lib_um.chm, vidjet ćemo da svi korišteni parametri funkcije imaju vezu na vlastiti opis, gdje će biti naznačene njihove moguće vrijednosti. Same funkcije također imaju poveznicu na vlastiti opis i izvorni kod. Ovo je vrlo korisno jer znajući što funkcija radi, možemo pratiti kako to radi, koji bitovi perifernih registara i kako utječe. Ovo je, prvo, još jedan izvor informacija za ovladavanje kontrolerom, koji se temelji na praktičnoj upotrebi kontrolera. Oni. prvo riješite tehnički problem, a zatim proučite samo rješenje. Drugo, ovo je polje za optimizaciju programa za one koji nisu zadovoljni s knjižnicom u smislu brzine rada i količine koda.



Naznačio sam da je standardna knjižnica spojena na sustav. Zapravo, povezan je CMSIS - sustav generaliziranog strukturnog prikaza MK, kao i SPL - standardna periferna biblioteka. Razmotrimo svaki od njih:

CMSIS
To je skup datoteka zaglavlja i mali skup koda za objedinjavanje i strukturiranje rada s kernelom i periferijama MK-a. Zapravo, bez ovih datoteka nemoguće je normalno raditi s MK-om. Knjižnicu možete nabaviti na MK stranici.
Ova knjižnica, ako vjerujete u opis, stvorena je za objedinjavanje sučelja pri radu s bilo kojim MK-om iz obitelji Cortex. Međutim, u stvarnosti se ispostavilo da to vrijedi samo za jednog proizvođača, t.j. kada prijeđete na MK druge tvrtke, prisiljeni ste proučavati njezinu periferiju gotovo ispočetka.
Iako su datoteke koje se odnose na jezgru procesora MK identične za sve proizvođače (makar samo zato što imaju isti model jezgre procesora - pruža ARM u obliku ip-blokova).
Stoga je rad s takvim dijelovima jezgre kao što su registri, upute, prekidi i koprocesorski blokovi standardan za sve.
Što se periferije tiče, STM32 i STM8 (odjednom) su gotovo slični, to djelomično vrijedi i za ostale MC-e koje je objavio ST. U praktičnom dijelu pokazat ću vam kako je jednostavno koristiti CMSIS. Međutim, poteškoće u korištenju povezane su s nevoljkošću ljudi da pročitaju dokumentaciju i razumiju MK uređaj.

SPL
Standardna periferna knjižnica je standardna periferna knjižnica. Kao što ime govori, svrha ove biblioteke je stvoriti apstrakciju za MK periferiju. Knjižnica se sastoji od datoteka zaglavlja u kojima su deklarirane čovjeku čitljive konstante za konfiguriranje i rad s MK periferijama, kao i datoteke izvornog koda koje se sklapaju u samu knjižnicu za operacije s periferijama.
SPL je apstrakcija preko CMSIS-a, koja korisniku predstavlja zajedničko sučelje za sve MCU-ove, ne samo jednog proizvođača, već općenito za sve MCU-ove s procesorskom jezgrom Cortex-Mxx.
Vjeruje se da je prikladnije za početnike, jer omogućuje vam da ne razmišljate o tome kako periferni uređaji rade, ali kvaliteta koda, svestranost pristupa i ograničenja sučelja nameću određena ograničenja programeru.
Također, funkcionalnost knjižnice ne dopušta vam uvijek točnu implementaciju konfiguracije nekih komponenti kao što je USART (univerzalni sinkroni-asinkroni serijski port) u određenim uvjetima. U praktičnom dijelu opisat ću i način rada s ovim dijelom knjižnice.

Pozdrav svima. Kao što se sjećate u prošlom članku, konfigurirali smo softverski paket za rad s STM32 mikrokontrolerima i sastavili prvi program. U ovom postu ćemo se upoznati s arhitekturom ove ploče, mikrokontrolerom i dostupnim knjižnicama za rad.

Ispod je slika ploče STM32F3 Discovery , gdje je: 1 - MEMS senzor. 3-osni digitalni žiroskop L3GD20. 2 - MEMS sustav 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 je crvena. Zelena znači komunikaciju između ST-LINK / v2 (ili V2-B) i PC-a. Imam ST-LINK / v2-B kao i prilagođeni USB priključak. 6.-LD3 / 10 (crvena), LD4 / 9 (plava), LD5 / 8 (narančasta) i LD6 / 7 (zelena). U prošlom postu smo treperili LED4 LD4. 7. - Dvije tipke: korisnik USER i RESET. 8. - USB KORISNIK s Mini-B konektorom.

9 - USB debuger / programator ST-LINK / V2. jedan 0. - Mikrokontroler STM32F303VCT6. 11. - Vanjski visokofrekventni generator 8 MHz. 12. - Trebao bi postojati niskofrekventni generator, nažalost nije zapečaćen. 13. - SWD - sučelje. 14. - Jumpere za odabir programiranja vanjskih ili unutarnjih, u prvom slučaju, moraju biti uklonjeni. 15 - Jumper JP3 - kratkospojnik, dizajniran za spajanje ampermetra za mjerenje potrošnje regulatora. Jasno je ako se ukloni, onda se naš kamenčić neće pokrenuti. 16. - STM32F103C8T6 na njemu se nalazi ploča za otklanjanje pogrešaka. 17. - LD3985M33R Regulator s niskim padom napona i razinom buke, 150mA, 3.3V.

Sada pogledajmo pobliže arhitekturu mikrokontrolera STM32F303VCT6. Njegove tehničke karakteristike: LQFP-100 paket, ARM Cortex-M4 jezgra, maksimalna frekvencija jezgre 72 MHz, programska memorija 256 KB, vrsta FLASH programske memorije, SRAM 40 KB, RAM 8 KB, broj I/O 87, sučelja ( CAN , I²C, IrDA, LIN, SPI, UART / USART, USB), periferne jedinice (DMA, I2S, POR, PWM, WDT), ADC / DAC 4 * 12 bit / 2 * 12 bit, napon napajanja 2 ... 3,6 V, radna temperatura -40 ... ... + 85 C. Na slici ispod, pinout, gdje vidimo 87 I/O portova, od kojih 45 Normalni I/O (TC, TTa), 42 5-voltna tolerantna I / Os (FT, FTf) - 5V kompatibilan (5V pinovi na desnoj strani, 3,3V pinovi na lijevoj strani). Svaka digitalna I/O linija može djelovati kao zajednička I/O linija.
odredišnu ili alternativnu funkciju. U tijeku projekata dosljedno ćemo se upoznavati s periferijom.

Razmotrite blok dijagram ispod. Srce je 32-bitna ARM Cortex-M4 jezgra koja radi do 72 MHz. Ima ugrađen FPU s pomičnim zarezom i jedinicu za zaštitu memorije MPU, ugrađene ćelije za praćenje makroa - Embedded Trace Macrocell (ETM), koji se može koristiti za praćenje izvršavanja glavnog programa unutar mikrokontrolera. Oni su u stanju kontinuirano emitirati ova opažanja kroz ETM pinove sve dok uređaj radi. NVIC (Nested vectored interrupt controller) - upravljački modul prekida. TPIU (Jedinica sučelja luka za praćenje). Sadrži memoriju FLASH -256 KB, SRAM 40 KB, RAM 8 KB. Između jezgre i memorije nalazi se matrica sabirnice koja omogućuje izravno povezivanje uređaja. Također ovdje vidimo dvije vrste sabirničkih matrica AHB i APB, gdje je prva produktivnija i koristi se za povezivanje brzih internih komponenti, a druga za periferne uređaje (ulazno/izlazne uređaje). Kontroler ima 4 12-bitna ADC-a (5Mbit/s) i temperaturni senzor, 7 komparatora (GP Comparator1 ... 7), 4 programabilna operacijska pojačala (OpAmp1 ... 4) (PGA (Programmable Gain Array)), 2 12-bitni DAC kanali, RTC (sat realnog vremena), dva watchdog timera - neovisna i prozorska (WinWatchdog i Ind. WDG32K), 17 mjerača opće namjene i višenamjenskih mjerača vremena.

Općenito, pogledali smo arhitekturu kontrolera. Sada razmotrite dostupne softverske knjižnice. Nakon što smo napravili pregled, možemo izdvojiti sljedeće: CMSIS, SPL i HAL. Pogledajmo svaki koristeći jednostavan primjer trepereće LED diode.

1). CMSIS(Cortex Microcontroller Software Interface Standard) je standardna biblioteka za Cortex®-M. Pruža podršku za uređaj i pojednostavljuje programska sučelja. CMSIS pruža dosljedna i jednostavna sučelja za kernel, njegove periferne uređaje i operativne sustave u stvarnom vremenu. Njegova uporaba je profesionalni način pisanja programa, jer pretpostavlja izravno upisivanje u registre i, sukladno tome, potrebno je stalno čitanje i proučavanje podatkovnih tablica. Neovisno o dobavljaču na razini hardvera.
CMSIS uključuje sljedeće komponente:
- CMSIS-CORE: dosljedno pokretanje sustava i periferni pristup;
- CMSIS-RTOS: Determinističko izvršavanje softvera u stvarnom vremenu
- CMSIS-DSP: Brza implementacija digitalne obrade signala;
- CMSIS-Driver: Generička periferna sučelja za međuverski i aplikacijski kod;
- CMSIS-Pack: Jednostavan pristup softverskim komponentama za višekratnu upotrebu;
- CMSIS-SVD: dosljedan pogled na uređaj i periferne uređaje
- CMSIS-DAP: Povezivost s jeftinim hardverom za evaluaciju. Softver za otklanjanje pogrešaka.

Na primjer, napišimo program - treperi LED. 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 MCU-ovi bazirani na ARM®, kao i opis specifične noge za koju je odgovoran DS9118: Cortex®-M4 32b MCU + FPU na bazi ARM®, do 256 KB Flash + 48 KB SRAM, 4 ADC-a, 2 DAC kanala, 7 komp, 4 PGA, mjerači vremena, 2,0-3,6 V. Za početak ćemo učitati port u program, budući da prema zadanim postavkama sve je onemogućeno, čime se postiže smanjena potrošnja energije. Otvorite Referentni priručnik i pogledajte odjeljak Reset i kontrola sata dalje na karti RCC registra i pogledajte koji je registar odgovoran za omogućavanje IOPEEN-a

Prijeđimo na opis vremena periferije 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 za uključivanje niske / visoke razine na nozi. Ispod je program:

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

2). SPL(Knjižnica standardnih perifernih uređaja)- ova knjižnica je dizajnirana za integraciju svih procesora tvrtke ST Electronics. Dizajniran da pojednostavi prenosivost koda i prvenstveno je namijenjen programerima početnicima. ST radi na zamjeni za SPL pod nazivom "niski sloj" koja je kompatibilna s HAL-om. Upravljački programi niskog sloja (LL) dizajnirani su tako da pružaju gotovo lagani sloj orijentiran na stručnjake koji je bliži hardveru od HAL-a. Osim HAL-a, dostupni su i LL API-ji. Primjer istog SPL programa.

#uključiti
#uključiti
#uključiti
#defini LED GPIO_Pin_8
int main () (
dugo ja;
GPIO_InitTypeDef gpio;
// Plava LED je spojena na port E, pin 8 (AHB sabirnica)
RCC_AHBPeriphClockCmd (RCC_AHBPeriph_GPIOE, OMOGUĆI);
// Konfiguriraj priključak E (LED)
GPIO_StructInit (& gpio); // deklarirati i inicijalizirati varijablu strukture podataka
gpio.GPIO_Mode = GPIO_Mode_OUT;
gpio.GPIO_Pin = LED;
GPIO_Init (GPIOE, & gpio);
// Trepćuće LED diode
dok (1) (
// Uključeno
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 datoteke zaglavlja koje sadrže potrebne podatke, strukture, funkcije za upravljanje resetiranjem i sinkronizacijom, kao i za konfiguriranje I/O portova.

3). HAL- (Razina pristupa hardveru, sloj apstrakcije hardvera)- Još jedna uobičajena razvojna knjižnica. S kojim je za konfiguraciju izašao program CubeMX, koji smo s vama koristili u prošlom članku. Na istom mjestu smo napisali program za bljeskanje LED-a pomoću ove biblioteke. Kao što možete vidjeti na donjoj slici, kocka generira HAL i CMSIS drajvere. Pa, opišimo glavne datoteke koje se koriste:
- system_stm32f3x.c i system_stm32f3x.h- osigurati minimalni skup funkcija za konfiguriranje sustava takta;
- core_cm4.h - omogućuje pristup registrima jezgre i njezinih perifernih uređaja;
- stm32f3x.h - datoteka zaglavlja mikrokontrolera;
- startup_system32f3x.s - startni kod, sadrži tablicu vektora prekida, itd.

#include "main.h"
#include "stm32f3xx_hal.h"
void SystemClock_Config (void); / * Deklarirajte funkcije konfiguracije takta * /
statička praznina MX_GPIO_Init (neispravna); / * Inicijaliziraj I / O * /
int main (void) (
/ * Resetiranje svih perifernih uređaja, inicijalizira Flash sučelje i Systick. * /
HAL_Init ();
/ * Konfigurirajte sat sustava * /
SystemClock_Config ();
/ * Pokreni sve konfigurirane periferne uređaje * /
MX_GPIO_Init ();
dok (1) (
HAL_GPIO_TogglePin (GPIOE, GPIO_PIN_8); // Prebacite stanje noge
HAL_Odgoda (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){

}
/ ** Pokreće takt sabirnice CPU, AHB i APB * /
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){
_Rukovalac_greške (__FILE__, __LINE__);
}
/ ** Konfigurirajte vrijeme prekida Systick * /
HAL_SYSTICK_Config (HAL_RCC_GetHCLKFreq () / 1000);
/ ** Konfigurirajte Systick * /
HAL_SYSTICK_CLKSourceConfig (SYSTICK_CLKSOURCE_HCLK);
/ * Konfiguracija prekida SysTick_IRQn * /
HAL_NVIC_SetPriority (SysTick_IRQn, 0, 0);
}
/ ** Konfigurirajte pinove kao analogni ulaz i izlaz EVENT_OUT EXTI * /
statična praznina MX_GPIO_Init (void){
GPIO_InitTypeDef GPIO_InitStruct;
/ * Omogući sat GPIO portova * /
__HAL_RCC_GPIOE_CLK_ENABLE ();
/ * Konfigurirajte izlaznu razinu 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);
/ * Konfigurirajte 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 * datoteka, int red){
dok (1) (
} }
#ifdef USE_FULL_ASSERT

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

Možemo sažeti da je prva opcija, korištenjem CMSIS-a, manje glomazna. Za svaku knjižnicu postoji dokumentacija. U narednim projektima koristit ćemo HAL i CMSIS, koristeći konfiguracijski program STCube i, ako je moguće, koristiti registre izravno, bez softverskih omotača. Danas ćemo se zaustaviti na ovome. U sljedećem članku osvrnut ćemo se na osnovne principe izgradnje pametne kuće. Zbogom svima.

Vrhunski povezani članci