STM32F407(STM32F4-DISCOVERY) — nestandarta pieeja — standarta bibliotēkas 1. daļa. STM32F10x SPL konfigurēšana, izmantojot makro definīcijas

Līdz šim mēs esam izmantojuši standarta kodola bibliotēku - CMSIS. Lai konfigurētu portu vēlamajā darbības režīmā, mums bija jāgriežas, lai atrastu reģistru, kas atbild par noteiktu funkciju, un arī lielā dokumentā jāmeklē cita ar šo procesu saistīta informācija. Lietas kļūs vēl sāpīgākas un rutīnas, kad sāksim strādāt ar taimeri vai ADC. Reģistru skaits tur ir daudz lielāks nekā I/O portos. Manuāla iestatīšana aizņem daudz laika un palielina iespēju kļūdīties. Tāpēc daudzi cilvēki dod priekšroku darbam ar standarta perifērijas bibliotēku - StdPeriph. Ko tas dod? Vienkārši – paaugstinās abstrakcijas līmenis, nevajag iedziļināties dokumentācijā un pārsvarā domāt par reģistriem. Šajā bibliotēkā visi MK perifērijas darbības režīmi un parametri ir aprakstīti struktūru veidā. Tagad, lai konfigurētu perifērijas ierīci, jums tikai jāizsauc ierīces inicializācijas funkcija ar aizpildītu struktūru.

Zemāk ir attēls ar shematisku abstrakcijas līmeņu attēlojumu.

Mēs strādājām ar CMSIS (kas ir "vistuvāk" kodolam), lai parādītu, kā darbojas mikrokontrolleris. Nākamais solis ir standarta bibliotēka, kuru mēs tagad iemācīsimies izmantot. Tālāk nāk ierīču draiveri. Tie tiek saprasti kā *.c \ *.h faili, kas nodrošina ērtu programmatūras saskarni jebkuras ierīces vadīšanai. Piemēram, šajā kursā mēs nodrošināsim jūs ar max7219 mikroshēmas un esp8266 WiFi moduļa draiveriem.

Standarta projektā būs iekļauti šādi faili:


Pirmkārt, protams, tie ir CMSIS faili, kas ļauj standarta bibliotēkai strādāt ar kodolu, mēs jau par tiem runājām. Otrkārt, standarta bibliotēkas faili. Un, treškārt, lietotāju faili.

Bibliotēkas failus var atrast lapā, kas veltīta mērķa MK (mums tas ir stm32f10x4), sadaļā Dizaina resursi(CooCox IDE šie faili tiek lejupielādēti no izstrādes vides repozitorija). Katrai perifērijas ierīcei atbilst divi faili - galvene (*.h) un avota kods(*.c). Detalizēts apraksts var atrast atbalsta failā, kas atrodas tīmekļa vietnes bibliotēkas arhīvā.

  • stm32f10x_conf.h — bibliotēkas konfigurācijas fails. Lietotājs var pieslēgt vai atvienot moduļus.
  • stm32f10x_ppp.h — perifērijas galvenes fails. Ppp vietā var būt gpio vai adc.
  • stm32f10x_ppp.c - perifērijas ierīces draiveris, kas rakstīts C valodā.
  • stm32f10x_it.h - galvenes fails, kas ietver visus iespējamos pārtraukumu apstrādātājus (to prototipus).
  • stm32f10x_it.c ir veidnes avota koda fails, kas satur pārtraukuma pakalpojuma rutīnu (ISR) izņēmuma situācijām programmā Cortex M3. Lietotājs var pievienot savus ISR izmantotajām perifērijas ierīcēm.

Standarta bibliotēkā un perifērijas ierīcēs ir nosaukšanas funkcijas un apzīmējumi.

  • PPP ir perifērijas ierīču, piemēram, ADC, akronīms.
  • Sistēmas, galvenes un pirmkoda faili — sāciet ar stm32f10x_.
  • Vienā failā izmantotās konstantes ir definētas šajā failā. Vairākos failos izmantotās konstantes ir definētas galvenes failos. Visas konstantes perifērijas bibliotēkā visbiežāk tiek rakstītas ar LIELajiem burtiem.
  • Reģistri tiek uzskatīti par konstantēm un tiek saukti arī par LIELajiem burtiem.
  • Perifērijas funkciju nosaukumos ir iekļauts akronīms, piemēram, USART_SendData() .
  • Katras perifērijas ierīces konfigurēšanai tiek izmantota struktūra PPP_InitTypeDef, kas tiek nodota funkcijai PPP_Init().
  • Lai deinitializētu (iestatītu vērtību uz noklusējuma vērtību), varat izmantot funkciju PPP_DeInit().
  • Funkciju, kas ļauj iespējot vai atspējot perifērijas ierīces, sauc par PPP_Cmd().
  • Pārtraukšanas iespējošanas/atspējošanas funkciju sauc par PPP_ITConfig.

AR pilns saraksts varat vēlreiz apskatīt bibliotēkas atbalsta failu. Tagad pārrakstīsim mirgojošo LED, izmantojot standarta perifērijas bibliotēku!

Pirms darba sākšanas apskatīsim failu stm32f10x.h un atrodam rindiņu:

#define USE_STDPERIPH_DRIVER

Ja konfigurējat projektu no jauna, izmantojot bibliotēkas failus no lejupielādētā arhīva, jums būs jāatceļ šīs rindas komentāri. Tas ļaus jums izmantot standarta bibliotēku. Šī definīcija (makro) liks priekšapstrādātājam iekļaut failu stm32f10x_conf.h:

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

Šajā failā ir moduļi. Ja jums ir nepieciešami tikai konkrēti, atspējojiet pārējos, tas ietaupīs laiku kompilācijas laikā. Mums, kā jūs varētu nojaust, ir nepieciešami RTC un GPIO moduļi (tomēr nākotnē mums būs nepieciešami arī _bkp.h, _flash, _pwr.h, _rtc.h, _spi.h, _tim.h, _usart.h):

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

Tāpat kā iepriekšējo reizi, vispirms ir jāiespējo porta B pulksteņa aktivizēšana. To veic ar funkciju, kas deklarēta stm32f10x_rcc.h:

Nederīgs RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState);

FunctionalState enum ir definēts stm32f10x.h:

Typedef enum (DISABLE = 0, IESPĒJA = !DISABLE) FunctionalState;

Deklarēsim mūsu kājas iestatīšanas struktūru (to var atrast failā stm32f10x_gpio.h):

GPIO_InitTypeDef LED;

Tagad mums tas ir jāaizpilda. Apskatīsim šīs struktūras saturu:

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

Visus nepieciešamos uzskaitījumus un konstantes var atrast tajā pašā failā. Pēc tam pārrakstītajai funkcijai init_leds () būs šāda forma:

Void led_init() ( // Iespējot pulksteni RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); // Deklarēt struktūru un aizpildiet to GPIO_InitTypeDef LED; LED.GPIO_Pin = GPIO_Pin_0; LED.GPIO_Pin = GPIO_Pin_0; LED.GPIO_Speed=GPIO IO_Mo de_Out_PP; // Inicializējiet portu GPIO_Init(GPIOB, &LED);)

Pārrakstīsim galveno () funkciju:

Int main(void) ( led_init(); while (1) ( GPIO_SetBits(GPIOB, GPIO_Pin_0); aizkave (10000000); GPIO_ResetBits(GPIOB, GPIO_Pin_0); aizkave (10000000); ) )

Galvenais ir iejusties inicializācijas secībā: ieslēgt perifērijas pulksteni, deklarēt struktūru, aizpildīt struktūru, izsaukt inicializācijas metodi. Citas perifērijas ierīces parasti tiek konfigurētas līdzīgā veidā.

Šajā publikācijā es centīšos koncentrēties uz galvenajiem punktiem, lai ātri sāktu darbu ar STM32F10x mikrokontrolleriem, kuru pamatā ir ražošanas uzņēmuma STMicroelectronics standarta perifērijas ierīču bibliotēka.

Rakstā kā izstrādes vide tiks izmantota Eclipse CDT. Tā kā galvenā uzmanība tiks pievērsta programmas kodam, jūs varat droši veikt visas manipulācijas Code::Blocks.

ARM mikrokontrolleru vispārējā projekta struktūra ir aprakstīta manā rakstā.

Šeit es īsumā atgādināšu, ka, lai izveidotu projektu ARM mikrokontrolleriem (īpaši STM32F10x), jums būs nepieciešams linkera skripts un C-Startup fails.

Linkera skripts ir fails ar instrukcijām programmas koda un datu ievietošanai mikrokontrollera atmiņā. Tas var pavēlēt jūsu programmas kodu ielādēt Flash programmas atmiņā vai SRAM datu atmiņā.

Mikrokontrolleriem ar dažādu programmu un datu atmiņas apjomu ir nepieciešami dažādi izkārtojuma skripti. Tos var iegūt no mikrokontrolleru ražotāja - STMicroelectronics.
Izpakojiet STM32F10x standarta perifērijas bibliotēku no arhīva ARM_Toolchain/Lib/stm32f10x_stdperiph_lib.zip.
Tajā ir paraugprojekti dažādām izstrādes vidēm (IAR EWB, Keil uVision, Atollic True Studio utt.). Mums tuvākā ir Atollic True Studio, jo tā ir Eclipse modifikācija.
Dodieties uz direktoriju Project/StdPeriph_Template/TrueSTUDIO, tur ir vairāki apakšdirektoriji, kuru nosaukumi atbilst STM3210x-EVAL izstrādes paneļu nosaukumiem.

Uzziniet, kurš no šiem paneļiem izmanto to pašu mikrokontrollera līniju, ko jūsējā. Kopējiet failu stm32_flash.ld no atbilstošā direktorija uz savu projektu.

Tāpat ir iespējams izveidot universālu skriptu, kurā tiks mainīts tikai programmas un datu atmiņas apjoms atbilstoši izmantotajam mikrokontrollerim.

Startēšanas kodu (C-Startup) STM32 mikrokontrolleriem var rakstīt C vai Assembler valodā.
Lai gan STM32F10x standarta perifērijas bibliotēka (saīsināti STM32F10x SPL) bieži tiek kritizēta par kļūdām, tas ir vienkāršākais veids, kā ātri sākt STM32 programmēšanu.
Bet jūs vienmēr vēlaties, lai būtu kāda veida alternatīva. Patiesībā tādu ir daudz, piemēram, programmēšana montāžas valodā :)

Tas ir visgrūtākais un bezjēdzīgākais ceļš. Otrs veids ir izmantot CMSIS bibliotēku, kas nodrošina sintaksi, lai piekļūtu C valodas struktūrām, lai piekļūtu dažādām mikrokontrolleru perifērijas ierīcēm. Vienkāršākais un loģiskākais veids (manuprāt) ir izmantot bibliotēkas.

Ja jūs kategoriski iebilstat pret STM32F10x SPL, tad jums ir cita alternatīva - libopencm3 bibliotēka. Tajā lielākā daļa piemēru ir koncentrēti ap galveno mikrokontrolleru sēriju STM32F10x, taču ir tikai laika jautājums, kad parādīsies piemēri citām sērijām (STM32F2xx/4xx). Jūs vienmēr varat pievienoties libopencm3 projektam un paātrināt šo procesu.

CMSIS standarts arī nav obligāts lietošanai jūsu programmās.
Jūs varat iztikt bez tā, veltot zināmas pūles un laiku, lai ieviestu HAL (Hardware Abstraction Layer) līmeni programmēšanas valodā C.

Dažos gadījumos šī metode var būt vienīgā pieejamā veidā. Piemēram, jūsu organizācija izmanto pielāgotas mikroshēmas, kuru pamatā ir ARM izstrādāti skaitļošanas kodoli un nozarei specifiskas perifērijas ierīces.

Vai arī jums ir jāievieš programmatūra C valodā mikrokontrolleriem ar ARM9 kodolu, kuriem ražotāji koncentrējas uz gatavu operētājsistēmas(Linux, QNX, Windows CE), tāpēc ražotāji nedrīkst nodrošināt bibliotēkas programmēšanai C valodā tīrā veidā vai kombinācijā ar vieglāku RTOS.

Par laimi, mikrokontrolleru ražotāji, kuru pamatā ir Cortex-M3 kodols, nodrošina izstrādātājus ar lielu skaitu kodu bibliotēku. Tas attiecas arī uz STM32 mikrokontrolleriem.
Turpināsim apsvērt STM32F10x SPL bibliotēku. Mēs to apsvērsim, izmantojot piemēru.
Varat atvērt šo piemēru vai izveidot savu projektu no nulles, lai labāk izprastu visu notiekošā procesu.

Otrajā gadījumā es uzskaitīšu nepieciešamās darbības:

  • Izveidojiet jaunu tukšu projektu Eclipse
  • Kopējiet izkārtojuma skriptu un startējiet failu projektā
  • Izveidojiet jaunu vai kopējiet veidni Makefile
  • Izmantojot Makefile no mana piemēra kā veidni, jums ir jāizveido src, inc, bin, obj direktoriji projektā un jāizveido apakšdirektorijas Debug un Release bin un obj direktorijās.
  • Kopējiet nepieciešamos avota un galvenes failus no CMSIS un STM32F10x SPL bibliotēkām.
  • Veiciet nepieciešamās izmaiņas veidnes Makefile lietotāja iestatījumu sadaļā, ja tāda tiek izmantota.
  • Izveidojiet jaunus mērķus “Debug”, “cleanDebug”, “Release”, “cleanRelease”, “Program” Eclipse logā “make target”.
  • Palaidiet "Atkļūdošanas" mērķi un uzraugiet tā izpildi logā "Console".

Lai labāk izprastu materiālu, rakstu sadalīju vairākās neatkarīgās rindkopās, no kurām katra apraksta tikai vienu darba ar STM32F10x SPL bibliotēku aspektu.

STM32F10x SPL konfigurēšana, izmantojot makro definīcijas

Lai konfigurētu bibliotēku, tiek izmantotas iepriekš definētas makro vērtības, kuras mēs tagad apsvērsim.
Tos var iestatīt galvenes failos, izmantojot priekšapstrādātāja direktīvu #definēt vai nododiet makro definīciju vērtības caur taustiņu -D GCC kompilators.
Savā piemērā es izmantoju otro metodi.
Makefile mainīgajā DEFINĒT satur makro, kas nepieciešami STM32F10x SPL bibliotēkas kompilēšanai.
Makro definīcija STM32F10X_MD norāda, vai izmantotais mikrokontrolleris pieder līnijai Vidēja blīvuma.
Tas ietver mikrokontrollerus ar zibatmiņu no 64 līdz 128 kB.
Šajā tabulā ir uzskaitīti dažādu mikrokontrolleru sēriju makro nosaukumi:

Sērijas nosaukums Makro Apraksts
Zema blīvuma vērtības līnija STM32F10X_LD_VL ar zibatmiņas ietilpību 16 - 32 kB
Zems blīvums STM32F10X_LD
ar zibatmiņas ietilpību 16 - 32 kB
Vidēja blīvuma Vērtības līnija STM32F10X_MD_VL Zibatmiņa
64–128 KB
Vidēja blīvuma STM32F10X_MD STM32F101xx, STM32F102xx, STM32F103xx sērijas mikrokontrolleri ar zibatmiņu 64 - 128 kB
Augsta blīvuma vērtības līnija STM32F10X_HD_VL STM32F100xx sērijas mikrokontrolleri ar skaļumu
Zibatmiņa - 256 - 512kB
Liels blīvums STM32F10X_HD ar skaļumu
Zibatmiņa 256 - 512kB
XL blīvums STM32F10X_XL
Zibatmiņa 512 - 1024 kB
Savienojuma līnija STM32F10X_CL

Lai iestatītu mikrokontrollera takts frekvenci, failā system_stm32f10x.c ir jāatsauc makro ar nepieciešamo pulksteņa frekvences vērtību.

#ja noteikts (STM32F10X_LD_VL) || (definēts STM32F10X_MD_VL) || (definēts STM32F10X_HD_VL) #define SYSCLK_FREQ_24MHz 24000000 #else /* #define SYSCLK_FREQ_HSE HSE_VALUE */ /* #define SYSCLK_FREQ_24MHz 24000LK_24MHz 24000LK_000 */ 0000 */ /* #define SYSCLK_FREQ_48MHz 48000000 */ /* #define SYSCLK_FREQ_56MHz 56000000 * / #define SYSCLK_FREQ_72MHz 72000000 #endif

#ja noteikts (STM32F10X_LD_VL) || (definēts STM32F10X_MD_VL) || (definēts STM32F10X_HD_VL)

/* #define SYSCLK_FREQ_HSE HSE_VALUE */

#define SYSCLK_FREQ_24MHz 24000000

#cits

/* #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

Paredzētais lietojums kvarca rezonators ar frekvenci 8 MHz visiem galvenajiem
sērijas mikrokontrolleri, izņemot Connectivity līniju, kurai nepieciešams uzstādīt 25 MHz kvarca rezonatoru.
Ja izmantojat kvarca rezonatorus ar citām frekvences vērtībām, ir jāmaina makro HSE_VALUE vērtība stm32f10x.h galvenes failā un attiecīgi jāpielāgo visas atkarīgās funkcijas.
Makro USE_STDPERIPH_DRIVER mērķi nav grūti uzminēt – izmantot STM32F10x standarta perifērijas bibliotēku.
USE_FULL_ASSERT — programmas atkļūdošanai izmantojiet makro ASSERT.

Makro assert_param izmantošana bibliotēkā

Visas STM32F10x SPL bibliotēkas funkcijas izmanto makro assert_param, lai pārbaudītu savus argumentus.
Šis makro pārbauda izteiksmi, kas ietver funkcijas argumentu, kas tiek pārbaudīts, vai tas ir vienāds ar nulli. Ja izteiksmes vērtība ir nulle, tad tiek izsaukta argumentu kļūdu apstrādātāja funkcija assert_failed, pretējā gadījumā (izteiksme nav nulle), argumentu pārbaude izdodas.
Programmā ir jāievieš funkcija assert_failed.
Tas parāda kļūdas ziņojumu, faila nosaukumu un koda rindas numuru, kas izraisīja kļūdu.
Makro debug_printf var izvadīt, izmantojot USART, izmantojot standarta new_lib bibliotēku vai, piemēram, Čena kunga bibliotēku.

#define debug_printf xprintf /* printf */ #ifdef USE_FULL_ASSERT void assert_failed(uint8_t* fails, uint32_t rinda) ( debug_printf("Nepareiza parametru vērtība: fails %s rindā %d\r\n", fails, (int)rindiņa) ; while (1) ( ) )/* assert_failed */ #endif/*USE_FULL_ASSERT*/

#define debug_printf xprintf /* printf */

#ifdef USE_FULL_ASSERT

void assert_failed (uint8_t * fails , uint32_t rinda )

debug_printf( "Nepareiza parametru vērtība: fails %s rindā %d\r\n", fails , (int ) rinda ) ;

kamēr (1)

) /* assert_failed */

#endif/*USE_FULL_ASSERT*/

Jūsu kodā ieviestā funkcija assert_failed tiek izmantota tikai tad, ja ir deklarēts makro USE_FULL_ASSERT. Pretējā gadījumā viss atkļūdošanas kods tiek izslēgts no avota. Šī funkcionalitāte ir ieviesta draivera bibliotēkas iestatījumu galvenes failā 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* fails, uint32_t rinda); #else #define assert_param(expr) ((void)0) #endif /* USE_FULL_ASSERT */

#ifdef USE_FULL_ASSERT

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

void assert_failed (uint8_t * fails , uint32_t rinda ) ;

#cits

#define assert_param(ekspr) ((void)0)

#endif /* USE_FULL_ASSERT */

Šeit nav daudz ko skaidrot. Apskatīsim assert_param izmantošanas piemēru.

void set_param(uint8_t * parametrs, uint8_t vērtība) ( assert_param(param != NULL); *param = vērtība; )/*set_param*/

void set_param (uint8_t * param , uint8_t vērtība )

assert_param (param != NULL );

* param = vērtība ;

) /*set_param*/

Funkcija iestata parametra vērtību, izmantojot rādītāju, kas tiek nodots kā arguments. Ja makro USE_FULL_ASSERT nav deklarēts, mēs varam pieņemt, ka līnijas
assert_param(param != NULL) vienkārši nav kodā, pretējā gadījumā parametrs tiek pārbaudīts šajā definīcijā.
Ja rādītājs nav definēts, vērtība param != NULL būs nepatiesa un tiks izpildīta funkcija assert_failed, kas, izmantojot USART, izvadīs faila nosaukumu un rindas numuru ar kļūdu, un pēc tam tiks veikta cilpa, tādējādi novēršot vērtības saglabāšanu. piešķirts nedefinētai adresei atmiņā.
Jums vispār nav jāizmanto makro assert_param savā kodā, bet gan bibliotēkas kodā
STM32F10x SPL to izmanto visur.
Funkciju set_param var ieviest ar argumentu kļūdu pārbaudi, neizmantojot assert_param.

#define ERROR (-1) #define OK (0) int set_param(uint8_t * param, uint8_t value) (>int r = ERROR; if (param == NULL) atgriež r; *param = vērtība; r = OK; atgriezties r ; )/*set_param*/

#define KĻŪDA (-1)

#define OK (0)

int set_param (uint8_t * param , uint8_t vērtība )

int r = KĻŪDA ;

if (param == NULL )

atgriezties r ;

* param = vērtība ;

r = labi;

atgriezties r ;

) /*set_param*/

C-Startup fails STM32F10x SPL bibliotēkā

Sākuma kodā mikrokontrolleris sākotnēji tiek inicializēts, steks ir konfigurēts, BSS sadaļa tiek atiestatīta un tiek izsaukta galvenā funkcija main().
Sākuma kodam nav tiešas saistības ar STM32F10x SPL bibliotēku. Tomēr šajā sāknēšanas kodā pirms programmas main() funkcijas izsaukšanas tiek izsaukta mikrokontrollera inicializācijas funkcija SystemInit(), kas ir daļa no CMSIS.
To var viegli atrast CMSIS bibliotēkā.
Dodieties uz direktoriju Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x/startup/TrueSTUDIO un kopējiet vajadzīgo failu. Atliek tikai noskaidrot, kurai līnijai pieder jūsu projektā izmantotais mikrokontrolleris.
Lai to izdarītu, skatiet šo tabulu:

Sērijas nosaukums Faila nosaukums Apraksts
Zema blīvuma vērtības līnija startup_stm32f10x_ld_vl.s STM32F100xx sērijas mikrokontrolleri ar skaļumu
Zibatmiņa 16 - 32kB
Zems blīvums startup_stm32f10x_ld.s mikrokontrolleri sērijas STM32F101xx, STM32F102xx, STM32F103xx
ar zibatmiņas ietilpību 16 - 32 kB
Vidēja blīvuma Vērtības līnija startup_stm32f10x_md_vl.s mikrokontrolleri sērija STM32F100xx
Vidēja blīvuma startup_stm32f10x_md.s mikrokontrolleri sērijas STM32F101xx, STM32F102xx, STM32F103xx
ar zibatmiņas ietilpību 64 - 128 kB
Augsta blīvuma vērtības līnija startup_stm32f10x_hd_vl.s mikrokontrolleri sērija STM32F100xx
Liels blīvums startup_stm32f10x_hd.s mikrokontrolleri sērijas STM32F101xx, STM32F103xx
ar zibatmiņas ietilpību 256 - 512 kB
XL blīvums startup_stm32f10x_xl.s mikrokontrolleri sērijas STM32F101xx, STM32F103xx
ar zibatmiņas ietilpību 512 - 1024 kB
Savienojuma līnija startup_stm32f10x_cl.s STM32F105xx un STM32F107xx sērijas mikrokontrolleri

Startēšanas failā ir ietverti pārtraukumu un izņēmumu vektoru apdarinātāju nosaukumi, bet ir ieviests tikai atiestatīšanas vektoru apdarinātājs, kura ietvaros tiek veikta visa sākotnējā inicializācija pirms galvenās () funkcijas izsaukšanas.
Par visu pārējo izņēmumu apstrādātāju ieviešanu atbild lietojumprogrammas programmētājs. Ja jūsu programma neizmanto apdarinātājus, tie nav jāreģistrē. Ja rodas izņēmums, tiks izmantots noklusējuma apdarinātājs - programmas koda cilpa.

CMSIS bibliotēkas sastāvs

Kā jau tika rakstīts šajā publikācijā, CMSIS bibliotēka nodrošina piekļuvi mikrokontrollera perifērijas moduļiem, izmantojot C valodas struktūru elementus.
Šīs bibliotēkas īstenošana ir sadalīta divās daļās. Pirmā daļa nodrošina piekļuvi Cortex-M3 kodola perifērijai, bet otrā daļa nodrošina piekļuvi perifērijai konkrēts modelis mikrokontrolleris.
Tā kā CMSIS standarts ir vienāds visiem mikrokontrolleriem ar Cortex-M3 kodolu, pirmās daļas realizācija būs vienāda visiem ražotājiem, bet otrā daļa katram ražotājam būs atšķirīga.
CMSIS ietver vairākus galvenes un avota failus. Pirmajā daļā ir iekļauti faili:

  • kodols_cm3.h
  • kodols_cm3.c

Otrajā CMSIS daļā ir iekļauts C-Startup fails, kā arī šādi faili:

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

Galvenes fails stm32f10x.h satur makro definīcijas, lai piekļūtu stm32f10x mikrokontrolleru perifērijas moduļiem.
Faili system_stm32f10x.h un system_stm32f10x.c īsteno mikrokontrollera sākotnējo inicializāciju.

STM32F10x SPL bibliotēkas sastāvs un konfigurācija

Bibliotēka sastāv no avota un galvenes failiem ar tādu pašu nosaukumu kā perifērijas moduļiem ar prefiksu stm32f10x_.
Piemēram, mijiedarbības ieviešana ar USART moduli ir ietverta failos stm32f10x_usart.h un stm32f10x_usart.c.
Pastāv bibliotēkas elementu nosaukšanas konvencijas un noteikti kodēšanas noteikumi, kas ir aprakstīti dokumentācijā.
Bibliotēka satur perifērijas mikrokontrolleru moduļu draiveru ieviešanu.
Bibliotēkas elementu nosaukumos tiek izmantoti šādi perifērijas moduļu akronīmi:

Akronīms Perifērijas modulis
ADC analogo-digitālo pārveidotāju
BKP rezerves reģistri
VAR CAN interfeiss
CVK patēriņa kontrolieris
CRC kontrolsummu aprēķināšanas modulis
DAC ciparu-analogo pārveidotājs
DBGMCU mikrokontrollera atkļūdošana
DMA tiešās atmiņas piekļuves kontrolieris
EXTI ārējais pārtraukumu kontrolieris
FSMC ārējās atmiņas kontrolieris
FLASH Flash programmu atmiņa
GPIO vispārējas nozīmes I/O porti
I2C I2C interfeiss
I2S I2S (skaņas) interfeiss
IWDG neatkarīgs sargsuņa taimeris
NVIC ligzdots pārtraukumu kontrolieris
PWR jaudas kontrolieris
RCC atiestatīšana un pulksteņa kontrolieris
RTC reāllaika kontrolieris (pulkstenis)
SDIO SDIO interfeiss
SPI SPI interfeiss
SysTick sistēmas taimeris
TIM pamata vai uzlabots taimeris
USART universāls seriālais sinhronais-asinhronais
raiduztvērējs
WWDG logu sargsuns

Pamatojoties uz šiem akronīmiem, tiek veidoti bibliotēkas programmatūras moduļu nosaukumi. Jums nav jāizmanto visi bibliotēkas moduļi.
Lai projektā izmantotu tikai nepieciešamos moduļus, bibliotēka ir jākonfigurē.
Šiem nolūkiem katram projektam, kurā tiek izmantota STM32F10x SPL bibliotēka, ir jābūt galvenes failam stm32f10x_conf.h.

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

#include "stm32f10x_gpio.h"

//#include "stm32f10x_i2c.h"

//#include "stm32f10x_iwdg.h"

//#include "stm32f10x_pwr.h"

#include "stm32f10x_rcc.h"

Lai iespējotu nepieciešamo moduli, jums ir jāatceļ direktīvas komentāri #iekļauts ar atbilstošajiem galvenes failiem.
Galvenes fails stm32f10x_conf.h ir iekļauts stm32f10x.h, tāpēc, lai izmantotu STM32F10x SPL bibliotēkas funkcijas, avota kodā ir jāiekļauj tikai viens galvenes fails stm32f10x.h.

// failā stm32f10x.h #ifdef USE_STDPERIPH_DRIVER #include "stm32f10x_conf.h" #endif

Es atkārtoju, ka projektā ir jādefinē arī makro USE_STDPERIPH_DRIVER, USE_FULL_ASSERT un makro, kas norāda izmantotā mikrokontrollera sēriju (piemēram, STM32F10X_MD vidēja blīvuma līnijai).
Ja izmantojat standarta kvarca frekvences vērtību un kontrolieris darbojas ar maksimālo takts frekvenci 72 MHz, tad nekas cits jums nav jāmaina.
Makefile ir jāpievieno bibliotēkas failu saraksts, ko apkopot.
Piemēram:

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

SRC += stm32f10x_rcc . c

SRC += stm32f10x_gpio . c

Izmantojot STM32F10x SPL bibliotēku. Darba mehānismi

Lai sāktu programmēšanu, izmantojot perifērijas bibliotēku, vienkāršākais veids ir apskatīt bibliotēkas komplektācijā iekļautos piemērus. Tomēr, lai saprastu šo piemēru kodu, jums ir jābūt pamatzināšanām par bibliotēkas sintaksi un lietošanu.
Visi iepriekš uzskaitītie perifērijas mikrokontrolleru moduļi sākotnēji ir deaktivizēti, tiem netiek piegādāts pulksteņa signāls un tie nepatērē elektrību.
Lai izmantotu perifērijas moduli, vispirms ir jānodrošina tam pulksteņa signāls. Pulksteņa signālu nodrošina RCC pulkstenis un atiestatīšanas modulis.
Šiem nolūkiem bibliotēkai ir šādas funkcijas:

RCC_AHBPeriphClockCmd(RCC_AHBPeriph_PPPx, IESPĒJOT); RCC_APB2PeriphClockCmd(RCC_APB2Periph_PPPx, IESPĒJOT); RCC_APB1PeriphClockCmd(RCC_APB1Periph_PPPx, IESPĒJOT);

RCC_AHBPeriphClockCmd(RCC_AHBPeriph_PPPx, IESPĒJOT);

RCC_APB2PeriphClockCmd (RCC_APB2Periph_PPPx, IESPĒJOT) ;

RCC_APB1PeriphClockCmd (RCC_APB1Periph_PPPx, IESPĒJOT) ;

Šeit PPP apzīmē moduļa aktonīma nosaukumu (piemēram, ADC vai USART), un x ir perifērijas moduļa numurs.
Vispirms jānoskaidro, kurai kopnei ir pievienots izmantotais modulis.
Kopumā mikrokontrolleriem ar Cortex-M3 pamata arhitektūru ir trīs kopnes:
instrukciju kopne, datu kopne un sistēmas kopne. Instrukciju kopne savieno kodolu ar Flash programmas atmiņu. Datu un sistēmas kopnes ir apvienotas AHB (ARM Hi-Speed ​​​​Bus) kopnes matricā, kas darbojas pamata frekvencē. Tomēr AHB kopnes frekvenci var samazināt, uzstādot sadalītājus. AHB kopne savieno ātrdarbīgas ierīces, piemēram, kodolu un DMA moduli.
I/O ierīces ir savienotas ar AHB kopni, izmantojot starpkopnes APB1 un APB2 (ARM Peripheral Bus).
APB2 kopnes maksimālā darba frekvence ir 72 MHz, APB1 kopnes frekvence
ierobežots līdz 36MHz.
Jūs varat uzzināt, ar kuru no kopnēm jūsu izmantotais perifērijas modulis ir pievienots, no dokumentācijas vai apskatīt galvenes failu stm32f10x_rcc.h.
Atveriet šo failu un pēc kārtas meklējiet RCC_AHBPeriph, RCC_APB1Periph un RCC_APB2Periph vērtības.

#define RCC_AHBPeriph_DMA1 ((uint32_t)0x00000001) #define RCC_AHBPeriph_DMA2 ((uint32_t)0x00000002) #define RCC_AHBPeriph_SRAM ((uint32_t)0FLi00x0CC0_0BIT F ((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)

Pēc makro nosaukumiem mēs nosakām, kuri moduļi ir savienoti ar kurām kopnēm. Varat arī izmantot veselo saprātu, lai noteiktu, kura riepa pieder vienai no trim. Piemēram, USART modulis ir ievades/izvades ierīce, kas nozīmē, ka tas ir savienots ar vienu no APB kopnēm. USART ir diezgan zema ātruma interfeiss, tāpēc tas, iespējams, ir savienots ar APB1 kopni.

#define RCC_APB1Periph_USART2 ((uint32_t)0x00020000) #define RCC_APB1Periph_USART3 ((uint32_t)0x00040000) #define RCC_APB1Periph_UART4 ((uint32_t)0x0_CC0_B8 ART5 ((uint32_t)0x00100000)

Pēc pulksteņa signāla nosūtīšanas uz perifērijas moduli varat konfigurēt tā parametrus, izsaucot inicializācijas funkciju:

PPP_Init(PPP, &PPP_InitStructure);

PPP_Init (PPP, & amp; PPP_InitStructure);

Tā kā inicializācijas funkcijai ir jānodod daudzi parametri, lai inicializētu perifērijas moduli, kā arguments tiek izmantots rādītājs uz struktūru. Pirms inicializācijas funkcijas izsaukšanas atmiņā ir jāizveido pati struktūra ar inicializācijas parametriem, struktūras elementiem jāpiešķir nepieciešamās vērtības:

PPP_InitTypeDef PPP_InitStructure = (val1, val2, ..., valN);/* struktūras inicializācija, kad tā ir deklarēta */

Vispirms varat izveidot struktūru un pēc tam piešķirt tās elementiem nepieciešamās vērtības:

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

PPP_InitTypeDef PPP_InitStructure ;

PPP_InitStructure . dalībnieks1 = val1 ;

PPP_InitStructure . dalībnieks2 = val2 ;

PPP_InitStructure . loceklisN = valN;

Apskatīsim piemēru no projekta stm32f10xQuickstart:

GPIO_InitTypeDef GPIO_InitStructure; #ifdef USE_STM32H_103 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, IESPĒJOT); 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, IESPĒJOT) ;

GPIO_InitStructure . GPIO_Pin = GPIO_Pin_12 ;

GPIO_InitStructure . GPIO_ātrums = GPIO_Ātrums_50MHz;

GPIO_InitStructure . GPIO_Mode = GPIO_Mode_Out_PP ;

GPIO_Init(GPIOC, & GPIO_InitStructure);

GPIO_InitStructure struktūras elementiem tiek piešķirta pin numura vērtība, porta režīms un ātrums.
Izsaucot funkciju GPIO_Init, tiek inicializēta GPIOC porta 12. rinda.
Pirmais funkcijas GPIO_Init arguments ir rādītājs uz GPIOC perifērijas ierīces atmiņas apgabalu, kas pārveidots par rādītāju uz GPIO_TypeDef struktūru.

// stm32f10x.h #define GPIOC ((GPIO_TypeDef *) GPIOC_BASE) #define GPIOC_BASE (APB2PERIPH_BASE + 0x1000) #define APB2PERIPH_BASE (PERIPH_BASE + 0x10000) 00) tipa def 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 struktūra

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 ;

GPIO_InitStructure struktūra ir GPIO_InitTypeDef tipa, kas aprakstīta galvenes failā
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, GPIO_ut_PPMode = 0x14, GPIO_ut_PPOde = 0x0 x1 C, GPIO_Mode_AF_PP = 0x18 )GPIOMode_TypeDef;

//stm32f10x_gpio.h

typedef struktūra

uint16_t GPIO_Pin ;

GPIOSpeed_TypeDef GPIO_Speed ​​​​;

GPIOMode_TypeDef GPIO_Mode ;

) GPIO_InitTypeDef ;

typedef enum

GPIO_Speed_10MHz = 1,

GPIO_Speed_2MHz,

GPIO_ātrums_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 ;

Kā redzat, inicializētās struktūras datu tipus var izmantot kā pielāgoti veidi, piemēram, GPIOSpeed_TypeDef, un datu tipi ar īpašām vērtībām perifērijas reģistru inicializācijas ērtībai, piemēram, GPIOMode_TypeDef.
Katras GPIO tapas konfigurēšanai ir piešķirti 4 biti.
Nākamajā attēlā parādīts GPIO nulles bita formāts:

Mode – izejas darbības režīms (ieeja/izvade). Precīzāk, šīs vērtības ir nedaudz lielākas; portiem, kas konfigurēti kā izejas porti, ir izejas signāla maksimālās frekvences ierobežojums.

Režīms Apraksts
00 ieeja
01 izejas frekvence līdz 10 MHz
10 izejas frekvence līdz 2 MHz
11 izejas frekvence līdz 50 MHz

CNF – izejas konfigurācijas biti. Atkarīgs no darbības režīma:

Piekrītiet, ka ar šo tapu konfigurācijas reģistra struktūru visu konfigurācijas bitu iestatīšana pašam būs ārkārtīgi neērta. To būs daudz vieglāk izdarīt, izmantojot GPIO_Init bibliotēkas funkciju.
Pēc perifērijas moduļa inicializācijas tas jāaktivizē, izmantojot funkciju PPP_Cmd:

PPP_Cmd(PPP, IESPĒJOT);

PPP_Cmd(PPP, IESPĒJOT);

Šī funkcija nepastāv GPIO moduļiem; pēc inicializācijas varat nekavējoties izmantot GPIO tapas. Jāatceras, ka bibliotēka nodrošina tikai saskarni ar mikrokontrollera aparatūru. Ja aparatūras modulim nav aktivizēšanas/deaktivizēšanas karoga, tad funkcijas izsaukums PPP_Cmd (PPP, IESPĒJOT) neiespējami.
Lai kontrolētu GPIOx tapas stāvokli izvades režīmā un nolasītu vērtību ievades vai izvades režīmā, bibliotēka nodrošina šādas funkcijas:

spēkā neesošs GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); spēkā neesošs 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);

tukšs GPIO_SetBits (GPIO_TypeDef * GPIOx , uint16_t GPIO_Pin ) ;

tukšs 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) ;

Pārējie perifērijas moduļi ir konfigurēti un darbojas tādā pašā veidā. Tomēr ir dažas atšķirības konkrētā aparatūras moduļa specifikas dēļ, tāpēc es ļoti iesaku vispirms apskatīt atlasītā moduļa izmantošanas piemērus STM32F10x SPL bibliotēkai.

Pārtraukumu un izņēmumu apstrāde

Cortex-M3 kodols ietver ligzdotu vektorizētu pārtraukumu kontrolieri. Kontrolieris atbalsta līdz 240 avotiem, kas var izraisīt procesora kodola pārtraukumus. Tas, cik daudz vektoru no 240 iespējamiem tiek realizēti konkrētā mikrokontrollera modelī, ir atkarīgs no ražotāja. Stm32f10x mikrokontrolleros var būt līdz 43 no šiem vektoriem. Šīs pārtraukumu līnijas sauc par maskējamām. Turklāt ir 15 Cortex-M3 kodola pārtraukumu vektori un viens ārējs nemaskējams EXTI pārtraukums.
Kontrolieris atbalsta ligzdotos pārtraukumus, kur vienā apdarinātājā var rasties cits pārtraukums. Šajā sakarā katram pārtraukuma avotam ir sava prioritāte. Tiek atbalstīti 16 pārtraukumu prioritātes līmeņi.
Cortex-M3 kodola pārtraukumu vektoriem ir visaugstākās prioritātes vērtības.
Trīs augstākie pārtraukumu līmeņi tiek piešķirti vektoriem, un tos nevar mainīt:

Numurs Apdarinātājs Prioritāte Apraksts
1 Reset_Handler -3 (augstākais) Atiestatīt vektoru
2 NMI_Handler -2 Nemaskējams pārtraukums
3 HardFault_Handler -1 Ārkārtas apstākļi

Visiem pārējiem pārtraukumu vektoriem var piešķirt prioritātes līmeņus no 0 līdz 15.
Augstākais prioritātes līmenis atbilst zemākai vērtībai. Prioritātes līmeni var piešķirt ne tikai atsevišķam vektoram, bet arī visai vektoru grupai. Šī funkcija atvieglo darbu ar lielu skaitu pārtraukumu vektoru.
Lai iestatītu prioritāro grupu, tiek izmantota funkcija no STM32F10x SPL bibliotēkas.

Ilgu laiku, pat ļoti ilgu laiku, par mūsu rakstu nav bijis neviena jauna raksta, tāpēc ir pienācis laiks sekot līdzi 😉 Šodien mēs sāksim pētīt STM32F4. Un, iespējams, sāksim ar jauna projekta izveidi šiem kontrolieriem, lai gan, godīgi sakot, es negribēju par to rakstīt rakstu, jo jauns projektsšeit tas principā tiek izveidots tāpat kā STM32F103 (). Bet joprojām gadās, ka ar STM32F4 rodas dažas grūtības, tāpēc tomēr sīkāk apsvērsim šo procesu)

Tātad, palaidīsim Keilu, izveidosim jaunu projektu - Projekts -> Jauns uVision projekts. Mēs saglabājam jauno projektu kādā mapē, un tad mums tiks lūgts izvēlēties izmantojamo mikrokontrolleri. Nu, izvēlamies, lai tas būtu STM32F407VG:

Gatavs, parādītajā dialoglodziņā noklikšķiniet uz “Jā”, un pirmais fails tiks pievienots mūsu projektam - startup_stm32f4xx.s. Tāpat kā iepriekš, mēs izmantosim bibliotēkas CMSIS Un Standarta perifērijas bibliotēka, bet, protams, jau STM32F4xx kontrolieriem. Tāpēc mums tie noteikti ir jālejupielādē un mūsu vēl tukšajam projektam jāpievieno nepieciešamie faili. Starp citu, ne reizi vien esmu dzirdējis no dažādiem cilvēkiem, ka viņi sastopas ar dažām “ne tik” bibliotēkām priekš F4, un pat visvienkāršākais projekts nav salikts. Es pats ar to neesmu saskāries, taču šeit ir pārbaudītās bibliotēkas, kuras pats izmantoju:

Tātad, mēs to lejupielādējām, viss ir gatavs, tagad mēs pievienojam failus projektam. Attēlā parādīts, kas jums būs nepieciešams:

Nu, sagatavošanās ir pabeigta, tagad izveidosim jaunu .c failu, kurā būs mūsu kods. Ejam uz Fails-> Jauns, Keil atveras tukšs fails, noklikšķiniet Fails-> Saglabāt kā un saglabājiet to, piemēram, ar nosaukumu test.c. Saglabājot, neaizmirstiet norādīt faila paplašinājumu (.c). Fails tika izveidots, lieliski, bet mums tas arī jāpievieno mūsu projektam. Nu, patiesībā, tajā nav nekā sarežģīta 😉 Ierakstīsim šajā failā tukšu testa programmu:

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

Gandrīz viss ir gatavs, atliek tikai apskatīt projekta iestatījumus - Projekts-> Mērķa opcijas… Atveras logs ar daudzām cilnēm, šeit mūs interesē tikai dažas. Atveriet cilni C/C++ un laukā Definēt mēs rakstām:

Nu lejā laukā jums jāpievieno ceļi uz absolūti visiem projektā iekļautajiem failiem. Pēc šīs darbības pabeigšanas varat nospiest F7 (Build), un projekts tiks izveidots bez kļūdām vai brīdinājumiem. Kā redzat, nekas sarežģīts)

Bet kopumā es personīgi daru lietas nedaudz savādāk. Apsveriet šīs pieejas trūkumus. Tātad mēs kaut kur lejupielādējām CMSIS un SPL bibliotēkas, pievienojām failus no šīm mapēm, pierakstījām ceļus līdz failiem, viss ir forši. BET! Projekts netiks veidots citā datorā, jo visi ceļi ir absolūti, tas ir, tie norāda uz noteiktām jūsu datora mapēm. Un citā mašīnā jums faktiski būs atkārtoti jāveic darbības, lai izveidotu jaunu projektu. Tas ir milzīgs mīnuss. Tāpēc es parasti izveidoju atsevišķu mapi jaunam projektam, tajā veidoju apakšmapes CMSIS, SPL un citām izmantotajām bibliotēkām un šajās mapēs ievietoju visus failus, kas man nepieciešami katrā konkrētajā projektā. Piemēram, izveidosim mūsu jaunajam projektam mapi STM32F4_Test un šādas mapes tajā:

Visus nepieciešamos failus, kurus pievienojām, veidojot projektu raksta sākumā, ievietoju CMSIS un SPL mapēs. Tagad mēs palaižam Keil, izveidojam jaunu projektu un saglabājam to mūsu Project apakšmapē, lai visi projekta faili būtu vienuviet un neradītu haosu)

Projekts ir izveidots, tagad, tāpat kā iepriekš, mēs tam vienkārši pievienojam visus failus no STM32F4_CMSIS un STM32F4_SPL mapēm. Mēs ievietojam mūsu testa .c failu ar funkciju main() mapē Source un pievienojam to arī projektam. Atliek tikai konfigurēt iestatījumus =) Viss ir pa vecam - definētajā laukā mēs rakstām:

USE_STDPERIPH_DRIVER,STM32F4XX



Saliekam projektu - kļūdu nav, lidojums normāls! Principā galu galā mēs saņēmām to pašu, bet tagad projekts tiks nekavējoties salikts jebkurā citā datorā bez problēmām, un tas ir ļoti ērti un noderīgi) Pilnīgi visi projekta faili tagad atrodas netālu, tajā pašā mapē, un ceļi ir kļuvuši relatīvi un nav jāmaina .
Tas arī viss, tuvākajā laikā mēs noteikti kaut ko darīsim, lai ieprogrammētu STM32F4, tāpēc uz drīzu tikšanos!;)

Pilns projekts no raksta parauga -

Es norādīju, ka standarta bibliotēka ir savienota ar sistēmu. Faktiski ir savienota CMSIS - MK vispārinātās strukturālās reprezentācijas sistēma, kā arī SPL - standarta perifērijas bibliotēka. Apskatīsim katru no tiem:

CMSIS
Tas ir galvenes failu kopums un neliels koda komplekts, lai apvienotu un strukturētu darbu ar MK kodolu un perifēriju. Patiesībā bez šiem failiem nav iespējams normāli strādāt ar MK. Bibliotēku varat iegūt MK pievienotajā dokumentācijas lapā.
Šī bibliotēka saskaņā ar aprakstu tika izveidota, lai unificētu saskarnes, strādājot ar jebkuru Cortex saimes MK. Taču patiesībā izrādās, ka tā ir tikai vienam ražotājam, t.i. Pārejot uz cita uzņēmuma mikrokontrolleri, jūs esat spiests izpētīt tā perifērijas ierīces gandrīz no nulles.
Lai gan tie faili, kas attiecas uz MK procesora kodolu, ir identiski no visiem ražotājiem (ja tikai tāpēc, ka tiem ir viens un tas pats procesora kodola modelis - IP bloku veidā nodrošina ARM).
Tāpēc darbs ar tādām kodola daļām kā reģistri, instrukcijas, pārtraukumi un kopprocesoru vienības ir standarta ikvienam.
Kas attiecas uz perifēriju, STM32 un STM8 (pēkšņi) ir gandrīz līdzīgi, un tas daļēji attiecas arī uz citiem ST izlaistajiem MK. Praktiskajā daļā parādīšu, cik viegli ir lietot CMSIS. Tomēr grūtības to lietot ir saistītas ar cilvēku nevēlēšanos lasīt dokumentāciju un izprast MK dizainu.

SPL
Standarta perifērijas bibliotēka - standarta perifērijas bibliotēka. Kā norāda nosaukums, šīs bibliotēkas mērķis ir radīt abstrakciju MK perifērijai. Bibliotēka sastāv no galvenes failiem, kuros deklarētas cilvēka lasāmās konstantes MK perifērijas ierīču konfigurēšanai un darbam ar tām, kā arī avota koda failiem, kas savākti pašā bibliotēkā darbībām ar perifērijas ierīcēm.
SPL ir CMSIS abstrakcija, kas lietotājam sniedz kopīgu saskarni visiem MCU ne tikai no viena ražotāja, bet kopumā visiem MCU ar Cortex-Mxx procesora kodolu.
Tiek uzskatīts, ka tas ir ērtāk iesācējiem, jo... ļauj nedomāt par to, kā darbojas perifērijas ierīces, bet koda kvalitāte, pieejas universālums un saskarņu ierobežojumi uzliek izstrādātājam zināmus ierobežojumus.
Tāpat bibliotēkas funkcionalitāte ne vienmēr ļauj precīzi ieviest dažu komponentu, piemēram, USART (universālais sinhronais-asinhronais seriālais ports) konfigurāciju noteiktos apstākļos. Praktiskajā daļā aprakstīšu arī darbu ar šo bibliotēkas daļu.

Sveiki visiem. Kā jūs atceraties pēdējā mūsu izveidotajā rakstā programmatūras pakotne darbam ar STM32 mikrokontrolleriem un sastādīja pirmo programmu. Šajā ierakstā mēs iepazīsimies ar šīs plates arhitektūru, mikrokontrolleru un darbam pieejamajām bibliotēkām.

Zemāk ir tāfeles attēls STM32F3 atklāšana , kur: 1 — MEMS sensors. L3GD20 3 asu digitālais žiroskops. 2 — MEMS sistēma korpusā, kas satur 3 asu digitālo lineāro akselerometru un 3 asu digitālo ģeomagnētisko sensoru LSM303DLHC. 4 – LD1 (PWR) – 3,3V barošanas avots. 5 – LD2 – sarkana/zaļa LED. Noklusējums ir sarkans. Zaļā krāsa nozīmē saziņu starp ST-LINK/v2 (vai V2-B) un datoru. Man ir ST-LINK/v2-B, kā arī pielāgots displejs USB ports. 6. -LD3/10 (sarkans), LD4/9 (zils), LD5/8 (oranžs) un LD6/7 (zaļš). Pēdējā ierakstā mēs mirgojām LD4 LED. 7. – Divas pogas: pielāgots LIETOTĀJS un atiestatīt RESET. 8. - USB LIETOTĀJS ar Mini-B savienotāju.

9 - USB atkļūdotājs/programmētājs ST-LINK/V2. 1 0. - Mikrokontrolleris STM32F303VCT6. 11. — Ārējais augstfrekvences ģenerators 8 MHz. 12. – Šeit vajadzētu būt zemfrekvences ģeneratoram, diemžēl tas nav pielodēts. 13. – SWD – interfeiss. 14. – Jumperi ārējo vai iekšējo kontrolieru programmēšanas izvēlei, pirmajā gadījumā jānoņem. 15 – Jumper JP3 – džemperis, kas paredzēts ampērmetra pievienošanai, lai mērītu kontroliera patēriņu. Skaidrs, ka, ja to izdzēsīs, tad mūsu akmens nesāksies. 16. – STM32F103C8T6 uz tā ir atkļūdošanas dēlis. 17. - LD3985M33R Regulators ar zemu sprieguma kritumu un trokšņu līmeni, 150mA, 3.3V.

Tagad apskatīsim tuvāk STM32F303VCT6 mikrokontrollera arhitektūru. Viņa tehniskās specifikācijas: LQFP-100 korpuss, ARM Cortex-M4 kodols, maksimālā serdeņa frekvence 72 MHz, programmas atmiņas ietilpība 256 KB, atmiņas tips FLASH programmas, apjoms brīvpiekļuves atmiņa SRAM 40 kbaiti, RAM 8 kbaiti, ieeju/izeju skaits 87, saskarnes (CAN, I²C, IrDA, LIN, SPI, UART/USART, USB), perifērijas ierīces (DMA, I2S, POR, PWM, WDT), ADC/DAC 4 *12 biti/2*12bit, barošanas spriegums 2...3,6 V, darba temperatūra –40...+85 C. Zemāk attēlā redzams spraudnis, kurā redzami 87 ieejas/izejas porti, no tiem 45 Parastās I/Os (TC, TTa), 42 5 voltu tolerantās I/Os (FT, FTf) – saderīgas ar 5 V. (uz plates ir 5V tapas labajā pusē, 3.3V pa kreisi). Katra digitālā I/O līnija var kalpot kā vispārēja I/O līnija.
galamērķis vai alternatīva funkcija. Projektiem virzoties uz priekšu, pamazām iepazīsimies ar perifēriju.

Apsveriet tālāk redzamo blokshēmu. Sirds ir 32 bitu ARM Cortex-M4 kodols, kas darbojas līdz 72 MHz. Tam ir iebūvēts peldošā komata bloks FPU un atmiņas aizsardzības bloks MPU, iebūvētas makro izsekošanas šūnas - Embedded Trace Macrocell (ETM), ar kurām var uzraudzīt galvenās programmas izpildi mikrokontrollera iekšpusē. Tie spēj nepārtraukti izvadīt šos novērojumus, izmantojot ETM kontaktus, kamēr ierīce darbojas. NVIC (Nested vectored interrupt controller) – pārtraukumu vadības modulis. TPIU (Trace Port Interface Unit). Satur FLASH atmiņu – 256 KB, SRAM 40 KB, RAM 8 KB. Starp kodolu un atmiņu ir kopnes matrica, kas ļauj tieši savienot ierīces. Arī šeit mēs redzam divu veidu kopnes matricas AHB un APB, kur pirmais ir produktīvāks un tiek izmantots ātrdarbīgai komunikācijai iekšējās sastāvdaļas, un pēdējais ir paredzēts perifērijas ierīcēm (ievades/izvades ierīcēm). Kontrolierim ir 4 12 bitu ADC (ADC) (5Mbit/s) un temperatūras sensors, 7 komparatori (GP Comparator1...7), 4 programmējami darbības pastiprinātāji (OpAmp1...4) (PGA (Programmable Gain Array)) ), 2 12 bitu DAC kanāli (DAC), RTC (reālā laika pulkstenis), divi sargsuņa taimeri - neatkarīgi un logu (WinWatchdog un Ind. WDG32K), 17 vispārējas nozīmes un daudzfunkcionāli taimeri.

Kopumā mēs apskatījām kontroliera arhitektūru. Tagad apskatiet pieejamās programmatūras bibliotēkas. Veicot pārskatu, mēs varam izcelt: CMSIS, SPL un HAL. Apskatīsim katru, izmantojot vienkāršu LED mirgošanas piemēru.

1). CMSIS(Cortex Microcontroller Software Interface Standard) — standarta bibliotēka Cortex®-M. Nodrošina ierīces atbalstu un vienkāršo programmatūras saskarnes. CMSIS nodrošina konsekventu un vienkāršas saskarnes kodolam, tā perifērijas ierīcēm un reāllaika operētājsistēmām. Tā izmantošana ir profesionāls programmu rakstīšanas veids, jo... ietver tiešu rakstīšanu reģistros, un attiecīgi ir nepieciešama pastāvīga datu lapu lasīšana un izpēte. Neatkarīgs no aparatūras ražotāja.
CMSIS ietver šādas sastāvdaļas:
- CMSIS-CORE: konsekventa sistēmas palaišana un perifērijas piekļuve;
- CMSIS-RTOS: Deterministiska reāllaika programmatūras izpilde programmatūraīsts laiks);
- CMSIS-DSP: ātra digitālā signāla apstrādes ieviešana digitālā apstrāde signāli);
- CMSIS draiveris: vispārīgas perifērijas saskarnes starpprogrammatūrai un lietojumprogrammu kodam (vispārējās perifērijas saskarnes starpprogrammatūrai un lietojumprogrammas kodam);
- CMSIS-Pack: ērta piekļuve atkārtoti lietojamiem programmatūras komponentiem programmatūras komponenti);
- CMSIS-SVD: konsekvents skats uz ierīci un perifērijas ierīcēm perifērijas ierīces);
- CMSIS-DAP: savienojamība ar zemu izmaksu novērtēšanas aparatūru. Atkļūdošanas programmatūra.

Piemēram, uzrakstīsim programmu – mirkšķināsim LED. Šim nolūkam mums ir nepieciešama dokumentācija, kas apraksta reģistrus. Manā gadījumā RM0316 Uzziņu rokasgrāmata STM32F303xB/C/D/E, STM32F303x6/8, STM32F328x8, STM32F358xC, STM32F398xE uzlaboti ARM ® balstīti MCU, kā arī konkrētās kājas apraksts, par kuru tā ir atbildīga. DS9118: uz ARM® balstīta Cortex®-M4 32b MCU+FPU, līdz 256 KB Flash+ 48 KB SRAM, 4 ADC, 2 DAC kanāli, 7 kompi, 4 PGA, taimeri, 2,0–3,6 V. Lai sāktu, mēs programmā pulksteni portu, jo Pēc noklusējuma viss ir atspējots, tādējādi samazinot enerģijas patēriņu. Atveriet uzziņu rokasgrāmatu un skatiet sadaļu Atiestatīšana un pulksteņa vadība, pēc tam RCC reģistra karti un skatiet, kurš reģistrs ir atbildīgs par IOPEEN iespējošanu.

Pāriesim pie šī reģistra perifērijas ierīču pulksteņa apraksta AHB perifērijas pulksteņa iespējošanas reģistrs (RCC_AHBENR), kur mēs redzam, ka šis ports atrodas zem 21. bita. Ieslēdziet to RCC->AHBENR|=(1<<21) . Далее сконфигурируем регистры GPIO. Нас интересует три: GPIOE_MODER и GPIOx_ODR . C помощью них повторим программу с предыдущей статьи, затактируем PE8. Первый отвечает за конфигурацию входа выхода, выбираем 01: General purpose output mode. GPIOE->MODER|=0 × 10000 . Otrais ir paredzēts zemā/augstā līmeņa ieslēgšanai uz kājas. Zemāk ir programma:

#include "stm32f3xx.h " //Mikrokontrollera galvenes fails
neparakstīts int i;
anulēta kavēšanās () (
priekš (i=0;i<500000;i++);
}
int main (neesošs) (
RCC->AHBENR|=(1<<21);
GPIOE->MODER|=0 × 10000;
kamēr (1)(
kavēšanās ();
GPIOE->ODR|=0×100;
kavēšanās ();
GPIOE->ODR&=~(0×100);
} }

2). SPL(Standarta perifēro ierīču bibliotēka)- šī bibliotēka ir paredzēta, lai apvienotu visus ST Electronics procesorus. Paredzēts koda pārnesamības uzlabošanai un galvenokārt paredzēts iesācējiem izstrādātājiem. ST ir strādājis pie SPL nomaiņas, ko sauc par "zemo slāni", kas ir saderīga ar HAL. Zema slāņa (LL) draiveri ir izstrādāti, lai nodrošinātu gandrīz vieglu, uz ekspertiem orientētu slāni, kas ir tuvāk aparatūrai nekā HAL. Papildus HAL ir pieejamas arī LL API. Tās pašas programmas piemērs SPL.

#iekļauts
#iekļauts
#iekļauts
#define LED GPIO_Pin_8
int main() (
garš i;
GPIO_InitTypeDef gpio;
// Zilā gaismas diode ir savienota ar portu E, tapu 8 (AHB kopne)
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOE, IESPĒJOT);
// Konfigurēt portu E (LED)
GPIO_StructInit(&gpio); //deklarē un inicializē datu struktūras mainīgo
gpio.GPIO_Mode = GPIO_Mode_OUT;
gpio.GPIO_Pin = LED;
GPIO_Init(GPIOE, &gpio);
// Mirgojošas gaismas diodes
kamēr (1) (
// Ieslēgts
GPIO_SetBits(GPIOE, LED);
par (i = 0; i< 500000; i++);
// Viss izslēgts
GPIO_ResetBits(GPIOE, LED);
par (i = 0; i< 500000; i++);
} }

Katra funkcija ir aprakstīta tehniskajā dokumentācijā UM1581 Lietotāja rokasgrāmata STM32F30xx/31xx standarta perifērijas bibliotēkas apraksts. Šeit mēs savienojam trīs galvenes failus, kas satur nepieciešamos datus, struktūras, atiestatīšanas un sinhronizācijas kontroles funkcijas, kā arī ievades/izvades portu konfigurēšanai.

3). HAL- (Aparatūras piekļuves līmenis, aparatūras abstrakcijas slānis)- Vēl viena kopīga bibliotēka attīstībai. Ar kuru tika izlaista arī CubeMX programma konfigurācijai, kuru izmantojām pēdējā rakstā. Tur mēs arī uzrakstījām programmu LED mirgošanai, izmantojot šo bibliotēku. Kā redzams attēlā zemāk, kubs ģenerē HAL un CMSIS draiverus. Nu, aprakstīsim galvenos izmantotos failus:
- system_stm32f3x.c un system_stm32f3x.h- nodrošināt minimālus funkciju komplektus laika noteikšanas sistēmas konfigurēšanai;
— core_cm4.h – nodrošina piekļuvi kodola un tā perifērijas ierīču reģistriem;
- stm32f3x.h - mikrokontrollera galvenes fails;
— startup_system32f3x.s — starta kods, satur pārtraukumu vektoru tabulu utt.

#include "main.h"
#include "stm32f3xx_hal.h"
void SystemClock_Config(void); /*Deklarēt pulksteņa konfigurācijas funkcijas*/
statisks tukšums MX_GPIO_Init(void); /*Inicializēt I/O*/
int main (neesošs) (
/*Visu perifērijas ierīču atiestatīšana, tiek inicializēts Flash interfeiss un Systick.*/
HAL_Init();
/* Konfigurēt sistēmas pulksteni */
SystemClock_Config();
/* Inicializēt visas konfigurētās perifērijas ierīces */
MX_GPIO_Init();
kamēr (1) (
HAL_GPIO_TogglePin(GPIOE, GPIO_PIN_8); //Pārslēdz kājas stāvokli
HAL_Delay(100); )
}
spēkā neesošs SystemClock_Config (neesošs){
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){

}
/**Inicializē CPU, AHB un APB kopņu pulksteņus */
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__);
}
/**Konfigurēt Systick pārtraukuma laiku*/
HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
/**Sistēmas konfigurēšana */
HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
/* SysTick_IRQn pārtraukuma konfigurācija */
HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
}
/** Konfigurēt tapas kā analogās ievades izvadi EVENT_OUT EXTI */
statisks tukšums MX_GPIO_Init (tukšums){
GPIO_InitTypeDef GPIO_InitStruct;
/* GPIO portu pulksteņa iespējošana */
__HAL_RCC_GPIOE_CLK_ENABLE();
/*Konfigurēt GPIO tapas izvades līmeni */
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);
/*Konfigurēt GPIO tapas: 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 * fails, int line){
kamēr (1) (
} }
#ifdef USE_FULL_ASSERT

Nederīgs assert_failed (uint8_t* fails, uint32_t rinda){
}
#endif
Šeit, tāpat kā iepriekšējā piemērā, mēs varam apskatīt, piemēram, katras funkcijas aprakstu dokumentācijā UM1786 lietotāja rokasgrāmata STM32F3 HAL un zema slāņa draiveru apraksts.

Mēs varam apkopot, ka pirmā iespēja, izmantojot CMSIS, ir mazāk apgrūtinoša. Katrai bibliotēkai ir dokumentācija. Turpmākajos projektos izmantosim HAL un CMSIS, izmantojot STCube konfigurācijas programmu un, ja iespējams, izmantosim reģistrus tieši, bez programmatūras iesaiņojumiem. Apstāsimies pie tā šodien. Nākamajā rakstā aplūkosim būvniecības pamatprincipus viedā māja. Čau visiem.




Tops