Si të konfiguroni telefonat inteligjentë dhe PC. Portali informativ
  • në shtëpi
  • OS
  • STM32F407(STM32F4-Zbulim) - Qasje jo standarde - Pjesa 1 e bibliotekës standarde.

STM32F407(STM32F4-Zbulim) - Qasje jo standarde - Pjesa 1 e bibliotekës standarde.

Edhe një herë dua të shkruaj për një fillim të thjeshtë me STM32, vetëm këtë herë pa përdorur shabllonet ose shembujt e dikujt tjetër - me një shpjegim për çdo hap. Artikujt do të kenë numërim të vazhdueshëm hapash.

1. Instaloni IAR

Ndërtimi i një projekti në IAR

1. Paraprocesor

  1. fshin komentet

2. Përpilues

3. Lidhës

3. Krijo një projekt të ri në IAR

Pas nisjes së IAR, shfaqet një dritare e qendrës së informacionit, e cila nuk na nevojitet. Klikoni në menynë Projekt -> Krijo projekt të ri. Zgjidhni zinxhirin e veglave: ARM (nuk ka gjasa të keni ndonjë gjë tjetër në atë listë), shabllonet e projektit: C –> kryesore.

Në dritaren e majtë ("Workspace"), kliko me të djathtën për të thirrur menunë dhe për të krijuar një grup të ri (Shto ->

Klikoni me të djathtën mbi CMSIS

Tek grupi fillimin

Përfundoi me CMSIS.

Tek grupi StdPeriphLib

Tek grupi përdorues

5. Vendosni projektin

  1. Opsionet e përgjithshme –> Synimi –>
Zgjidhni ST –> STM32F100 –> ST STM32F100xB. Ky është kontrolluesi ynë. 2. Opsionet e përgjithshme –> Konfigurimi i bibliotekës –> CMSIS: kontrolloni kutinë Përdor CMSIS. Pra, ne do të përdorim bibliotekën CMSIS të integruar në përpilues. Që nga versioni 6.30, IAR është dërguar me CMSIS të integruar dhe duket të jetë më mirë - por ka sjellë një konfuzion me projektet më të vjetra. 3. Kompiluesi C/C++ –>
$PROJ_DIR$\

* Debugger –> Setup –> Driver: zgjidhni ST-Link, pasi një programues i tillë është i integruar në tabelën Discovery. Tani ne konfigurojmë vetë programuesin: * Debugger –> ST-LINK –> Ndërfaqja: zgjidhni SWD (programuesi në tabelë është i lidhur me kontrolluesin përmes SWD, jo përmes JTAG). * Debugger –>
#include "stm32f10x_conf.h" 

void main()
{
ndërsa (1)
{
}
}

<1000000; i++);


për (i=0; i<1000000; i++);

#include "stm32f10x_conf.h"

void main()
{





int i;
ndërsa (1)
{

për (i=0; i<1000000; i++);

<1000000; i++); } }

arkiv me projektin GPIO. Për fat të mirë, mund ta ruani këtë projekt dhe ta përdorni si shabllon, në mënyrë që të mos keni nevojë ta bëni të gjithë konfigurimin përsëri. I gjithë cikli: 1. Portat I / O (/index.php/stm32-from_zero_to_rtos-2_timers/ "STM32 - nga zero në RTOS. 2: Kohëmatësi dhe ndërprerjet") (/index.php/stm32-from_zero_to_rtos-3_timer_outs/ STM32 - Nga zero në RTOS. 3: Daljet e kohëmatësit") [Edhe një herë dua të shkruaj për një fillim të thjeshtë me STM32, vetëm këtë herë pa përdorur shabllonet ose shembujt e dikujt - me një shpjegim për çdo hap. Artikujt do të kenë numërim të vazhdueshëm hapash.

0. Merrni tabelën e zbulimit STM32VLD

Ne blejmë në dyqan, kushton 600 rubla. Do t'ju duhet të instaloni drejtuesit në tabelë - mendoj se kjo nuk do të shkaktojë vështirësi.

1. Instaloni IAR

Ne do të punojmë në IAR - një IDE e mirë me një përpilues të shkëlqyer. I mungon komoditeti i shkrimit të kodit - por për qëllimet tona është mjaft e mjaftueshme. Unë jam duke përdorur versionin IAR 6.50.3, merrni - ju e dini ku.

2. Shkarkoni bibliotekën periferike

Unë nuk jam mbështetës i punës me regjistra në fazën e trajnimit. Prandaj, unë sugjeroj të shkarkoni bibliotekën periferike nga ST për të marrë funksione të përshtatshme aksesi në të gjitha cilësimet e nevojshme.

Ne krijojmë dosjen "STM32_Projects", shtojmë dosjen "Libraries" nga arkivi i shkarkuar (stsw-stm32078.zip/an3268/stm32vldiscovery_package) atje, ai përmban CMSIS (bibliotekë ARM për të gjithë mikrokontrolluesit Cortex, përshkrimin dhe adresat e të gjitha burimeve STsw-stm32078.zip/an3268/stm32vldiscovery_10 dhe erix) bibliotekë periferike nga ST me të gjitha veçoritë.

Ne gjithashtu krijojmë një dosje “1. GPIO”, i cili do të përmbajë projektin tonë të parë.

Pema e dosjeve - në foto. Bëni vetëm këtë, sepse atëherë shtigjet relative në këtë pemë do të jenë shumë të rëndësishme.

Epo, për të kuptuar se çfarë është në rrezik - shkarkoni dokumentin prej 1100 faqesh për këta kontrollues.

Ndërtimi i një projekti në IAR

Është e nevojshme të kuptohet qartë thelbi i procesit të montimit të projektit. Për lehtësi, le ta ndajmë atë në faza.

1. Paraprocesor

Një paraprocesor kalon nëpër të gjithë skedarët .c të projektit (si main.c ashtu edhe të gjithë skedarët në hapësirën e punës). Ai bën sa vijon:

  1. fshin komentet
  2. zgjeron #include direktivat, duke i zëvendësuar ato me përmbajtjen e skedarit të specifikuar. Ky proces funksionon në mënyrë rekursive, duke filluar nga skedari .c dhe duke hyrë në çdo #include .h që haset, dhe nëse direktivat #include gjenden gjithashtu në skedarin .h, paraprocesori do të hyjë gjithashtu në to. Rezulton një pemë e tillë përfshirjesh. Ju lutemi vini re: nuk trajton situatën e përfshirjes së dyfishtë, d.m.th. i njëjti skedar .h mund të përfshihet disa herë nëse #përfshihet në shumë vende në projekt. Kjo situatë duhet të trajtohet me përkufizime.
  3. kryen zëvendësim makro - zgjeron makro
  4. mbledh direktivat e përpiluesit.

Paraprocesori gjeneron skedarë .i, të cilët janë mjaft të dobishëm kur kërkoni për gabime ndërtimi - qoftë edhe vetëm sepse të gjitha makrot janë zgjeruar plotësisht në to. Ruajtja e këtyre skedarëve mund të aktivizohet në cilësimet e projektit.

Në këtë pikë, ndërtuesi i ka të gjithë skedarët .c në projekt gati për t'u kompiluar - si skedarë .i. Nuk ka ende lidhje midis skedarëve.

2. Përpilues

Pas kalimit të paraprocesorit, përpiluesi optimizon dhe përpilon çdo skedar .i, duke prodhuar një kod binar. Këtu duhet të specifikoni llojin e procesorit, memorien e disponueshme, gjuhën e programimit, nivelin e optimizimit dhe gjëra të ngjashme.

Çfarë bën përpiluesi kur ndeshet me një thirrje funksioni në një skedar .c që nuk përshkruhet në këtë skedar? Ai e kërkon atë në titujt kryesorë. Nëse titujt thonë se funksioni është në një skedar tjetër .c, ai thjesht lë një tregues në atë skedar tjetër në atë vend.

Në këtë pikë, ndërtuesi i ka të gjithë skedarët .c të projektit të përpiluar në skedarë .o. Ato quhen module të përpiluara. Tani ka lidhje midis skedarëve në formën e treguesve në vendet ku thirren funksionet "të huaja" - por këto janë ende disa skedarë të ndryshëm.

3. Lidhës

Pothuajse gjithçka është gati, thjesht duhet të kontrolloni të gjitha lidhjet midis skedarëve - kaloni në main.o dhe zëvendësoni treguesit për funksionet e njerëzve të tjerë - modulet e përpiluara. Nëse nuk përdoret ndonjë funksion nga bibliotekat, ai ose nuk do të kompilohet fare në fazën e mëparshme, ose nuk do të zëvendësohet askund nga lidhësi (në varësi të metodës së kolektorit). Në çdo rast, nuk do të futet në kodin binar të përfunduar.

Lidhësi gjithashtu mund të kryejë disa veprime përfundimtare me binarin, për shembull, të llogarisë kontrollin e tij.

Projekti i parë - puna me portet I/O

3. Krijo një projekt të ri në IAR

Pas nisjes së IAR, shfaqet një dritare e qendrës së informacionit, e cila nuk na nevojitet. Klikoni në menynë Projekt -> Krijo projekt të ri. Zgjidhni zinxhirin e veglave: ARM (nuk ka gjasa të keni ndonjë gjë tjetër në atë listë), shabllonet e projektit: C –> kryesore.

Tani keni një projekt të ri bosh C dhe një skedar main.c.

4. Ne lidhemi me projektin e bibliotekës

Në dritaren e majtë ("Hapësira e punës"), kliko me të djathtën për të thirrur menunë dhe për të krijuar një grup të ri (Shto -> Shto grup), le ta quajmë CMSIS. Le të krijojmë grupet StdPeriphLib, Startup dhe User në të njëjtën mënyrë. Tani shtoni skedarë në grupe (do të nënvizoj të gjithë skedarët për ta bërë më të lehtë ndjekjen).

Klikoni me të djathtën mbi CMSIS, Shtoni, Shtoni skedarë - shkoni te Bibliotekat / CMSIS / CM3, nga dosja DeviceSupport / ST / STM32F10x (mbështetje kristalore) merrni system_stm32f10x.c (ky është një përshkrim i periferisë së një kristali të veçantë dhe një cilësim i orës). Dosja CoreSupport (mbështetja e kernelit) gjithashtu përmban core_cm3.c (ky është një përshkrim i bërthamës Cortex M3), por ne nuk do ta marrim atë - sepse është tashmë në përpilues. Unë do të shkruaj për të më tej.

Tek grupi fillimin shtoni skedarin startup_stm32f10x_md_vl.s nga dosja Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x/startup/iar. Këta janë hapat që duhen kryer në fillim. Pothuajse plotësisht ky është konfigurimi i mbajtësve të ndryshëm të ndërprerjeve (vetë mbajtësit do të jenë pak më larg). Ka ende skedarë për kristale të tjera, por është md_vl që na intereson - kjo do të thotë densitet mesatar (sasi mesatare e memories, ka edhe kristale me vëllime të vogla dhe të mëdha), linjë vlere (linja e vlerësimit - kristali STM32F100 është menduar vetëm për vlerësimi i mundësive dhe kalimi në familjet vijuese).

Përfundoi me CMSIS.

Tek grupi StdPeriphLib shtoni skedarë stm32f10x_rcc.c dhe stm32f10x_gpio.c nga dosja Libraries/STM32F10x_StdPeriph_Driver/src. E para është funksioni i punës me sistemin e orës, dhe e dyta është puna me kunjat I/O.

Tek grupi përdorues zvarrit dhe lësho kryesoren tonë.c . Është opsionale, por është më e bukur në këtë mënyrë.

Tani pema e projektit GPIO duket kështu:

Hapësira e punës është gati, nuk do t'i shtojmë asgjë tjetër.

Mbetet vetëm për të vendosur një skedar më shumë në dosjen e projektit, duke lidhur titujt me të gjithë skedarët e bibliotekës periferike. Mund ta shkruani vetë, por është më e lehtë ta merrni të gatshme. Shkoni te stsw-stm32078.zip/an3268/stm32vldiscovery_package/Project/Examples/GPIOToggle - aty marrim skedarin stm32f10x_conf.h (konfigurimin e projektit) dhe e vendosim në "1. GPIO. Ky është i vetmi skedar i gatshëm që marrim.

stm32f10x_conf.h - vetëm një grumbull i përfshin modulet e nevojshme dhe funksionet e pohimit. Ky funksion do të thirret në rast të gabimeve në punën me funksionet e bibliotekës periferike: për shembull, vendosni pak mbeturina në funksionin GPIO_WriteBit në vend të GPIOC - me pak fjalë, ST u risigurua jashtëzakonisht shumë. Në këtë funksion, thjesht mund të ekzekutoni një lak të pafund - while(1); Ne ende duhet të shkojmë te stm32f10x_conf.h - për të komentuar linjat për përfshirjen e skedarëve të pajisjeve periferike të panevojshme, duke lënë vetëm stm32f10x_rcc.h, stm32f10x_gpio.h dhe misc.h - kështu që ne mund t'i shkruajmë vetë.

5. Vendosni projektin

Klikoni me të djathtën në dritaren Workspace mbi emrin e projektit:

  1. Opsionet e përgjithshme –> Target –> Varianti i procesorit: zgjidhni “Device”, shtypni butonin djathtas
Zgjidhni ST –> STM32F100 –> ST STM32F100xB. Ky është kontrolluesi ynë. 2. Opsionet e përgjithshme –> Konfigurimi i bibliotekës –> CMSIS: kontrolloni kutinë Përdor CMSIS. Pra, ne do të përdorim bibliotekën CMSIS të integruar në përpilues. Që nga versioni 6.30, IAR është dërguar me CMSIS të integruar dhe duket të jetë më mirë - por ka sjellë një konfuzion me projektet më të vjetra. 3. Kompiluesi C/C++ –> Paraprocesori. Këtu shkruajmë shtigjet në dosjet e bibliotekës:
$PROJ_DIR$\
$PROJ_DIR$\..\Libraries\CMSIS\CM3\DeviceSupport\ST\STM32F10x
$PROJ_DIR$\..\Libraries\STM32F10x_StdPeriph_Driver\inc
Makroja $PROJ_DIR$ do të thotë dosja aktuale (dosja e projektit) dhe .. do të thotë të ngjitesh një nivel. Ne kemi shkruar shtigjet për në dosje me përshkrimin e kristalit, si dhe për skedarët e kokës së bibliotekës periferike, pasi të gjithë skedarët .c në projekt përfshijnë kokën e tyre dhe përpiluesi duhet të dijë se ku t'i kërkojë ato. Gjithashtu këtu duhet të shkruani USE\_STDPERIPH\_DRIVER në simbolet e përcaktuara. Kjo do të përfshijë skedarët e kërkuar të konfigurimit (për shembull, stm32f10x_conf.h i përmendur) në projekt. Pra, skeda Preprocessor do të duket kështu: * Debugger –> Setup –> Driver: zgjidhni ST-Link, pasi një programues i tillë është i integruar në tabelën Discovery. Tani ne konfigurojmë vetë programuesin: * Debugger –> ST-LINK –> Ndërfaqja: zgjidhni SWD (programuesi në tabelë është i lidhur me kontrolluesin përmes SWD, jo përmes JTAG). * Debugger –> Shkarko: kontrolloni kutinë Përdorni ngarkuesin e flashit, “Ngarkoni firmware në memorien flash”. Logjikisht, pa të, asgjë nuk do të vërshojë.## 6. Shkrimi i kodit Dhe për fillim, unë do të shkruaj se çfarë do të bëjë ky kod. Do të demonstrojë një gjë të thjeshtë, ndezjen e një LED (PC8 në tabelën Discovery) me një pauzë në një lak të pafund. Ne përfshijmë skedarin e kokës së konfigurimit të projektit, stm32f10x\_conf.h. Në të gjejmë rreshtin #include "stm32f10x \ _exti.h" - ky është rreshti 35 dhe komentojeni atë me dy prerje. Fakti është se projekti ynë nuk ka nevojë për modulin EXTI. Ekziston tashmë një funksion int main në skedarin main.c dhe i vetmi veprim në të është kthimi 0. Hiqni këtë rresht (nuk do të kthejmë asnjë vlerë), ndryshoni llojin e funksionit në void (për të njëjtën arsye) , dhe shkruani një lak të pafund:
#include "stm32f10x_conf.h" 

void main()
{
ndërsa (1)
{
}
}

### Nisja e modulit GPIO Portat I/O STM32 quhen GPIO - Hyrja/Dalja me qëllim të përgjithshëm. Prandaj, ne përfshimë bibliotekën stm32f10x_gpio.c. Megjithatë, kjo nuk është gjithçka që na nevojitet, një teori e vogël: të gjitha pajisjet periferike në çip janë çaktivizuar si parazgjedhje, si nga energjia ashtu edhe nga frekuenca e orës. Për ta ndezur, duhet të jepni një sinjal orësh. Kjo menaxhohet nga moduli RCC dhe ekziston një skedar stm32f10x_rcc.c për të punuar me të. Moduli GPIO varet në autobusin APB2. Ekziston edhe AHB (një analog i autobusit procesor-urë veri) dhe APB1 (si dhe APB2 - një analog i autobusit urë veri-ura jugore). Prandaj, gjëja e parë që duhet të bëjmë është të aktivizojmë klockimin e modulit GPIOC. Ky është moduli përgjegjës për PORTC; ka edhe GPIOA, GPIOB e kështu me radhë. Kjo bëhet si kjo: RCC\_APB2PeriphClockCmd(RCC\_APB2Periph_GPIOC, ENABLE); Është e thjeshtë - ne e quajmë funksionin e furnizimit të një sinjali të orës nga autobusi APB2 në modulin GPIOC, dhe kështu aktivizojmë këtë modul. Sigurisht, ne e bëjmë këtë që në fillim të funksionit kryesor të zbrazët. Këtu janë vetëm bazat që duhet të kuptoni. Kam gjithashtu një [artikull të detajuar rreth modulit GPIO] (/index.php/stm32-%e2%86%92-%d0%bf%d0%be%d1%80%d1%82%d1%8b- gpio / "STM32 → portet GPIO"). ### Konfigurimi i modulit GPIOC Nuk ka mbetur shumë për të konfiguruar modulin GPIOC. Vendosim kunjin në dalje (ka edhe funksione hyrëse dhe alternative), rregullojmë mprehtësinë e pjesëve të përparme (për qëllimin e pajtueshmërisë me EM), drejtuesin e daljes (shtytje-tërheqje ose burim i hapur). Ne e bëjmë këtë menjëherë pas inicializimit të portit. 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); Kjo është e gjitha, pasi kunja PC8 do të funksionojë si një dalje shtytëse me skaje relativisht të lëmuara (frekuenca maksimale e ndërrimit është 2 MHz. Skajet e mprehta janë 50 MHz). Lehtësia e pjesëve të përparme nuk është e dukshme për syrin, por mund të shihet në oshiloskop. ### Ndizni LED-in Thirrni funksionin GPIO\_WriteBit(GPIOC, GPIO\_Pin\_8, Bit\_SET); LED do të ndizet. ### Ndizeni dhe çaktivizoni atë në një cikli Në ciklin while(1), shkruani kodin për ta ndezur, ndaloni, fikeni dhe ndaloni përsëri:

GPIO_WriteBit(GPIOC, GPIO_Pin_8, Bit_SET);  për (i=0; i<1000000; i++);

GPIO_WriteBit(GPIOC, GPIO_Pin_8, Bit_RESET);
për (i=0; i<1000000; i++);

Kështu, i gjithë skedari main.c duket si ky:

#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;
ndërsa (1)
{
GPIO_WriteBit(GPIOC, GPIO_Pin_8, Bit_SET);
për (i=0; i<1000000; i++);

GPIO_WriteBit(GPIOC, GPIO_Pin_8, Bit_RESET); për (i=0; i<1000000; i++); } }

## 7. Nisja! Ne e lidhim bordin e zbulimit STM32VLD me kompjuterin përmes microUSB, klikoni butonin Shkarko dhe korrigjim në IAR. Programi ngarkohet në mikrokontrollues (mund të vëreni një dritare me një shirit progresi që mbyllet shpejt - madhësia e programit është kaq e vogël) dhe fillon korrigjimi. IAR ndalon në udhëzimin e parë të kodit (kjo është mjaft e përshtatshme kur korrigjoni), duhet ta filloni me butonin Go. Gjithçka duhet të funksionojë - LED blu PC8 në bordin e zbulimit STM32VLD duhet Si gjithmonë, mund ta shkarkoni arkivin me projektin GPIO. Për fat të mirë, mund ta ruani këtë projekt dhe ta përdorni si shabllon, në mënyrë që të mos keni nevojë ta bëni të gjithë konfigurimin përsëri. I gjithë cikli: 1. Portat I / O (/index.php/stm32-from_zero_to_rtos-2_timers/ "STM32 - nga zero në RTOS. 2: Kohëmatësi dhe ndërprerjet") (/index.php/stm32-from_zero_to_rtos-3_timer_outs/ STM32 - Zero në RTOS. 3: Daljet e kohëmatësit")

](/index.php/stm32-from_zero_to_rtos-4_exti_nvic/ "STM32 - nga zero në RTOS. 4: Ndërprerjet e jashtme dhe NVIC") 5. Instalo FreeRTOS

Pra, ne jemi ngritur tashmë në këmbë, në kuptimin që kemi gjithçka që na nevojitet të lidhur me kunjat e mikrokontrolluesit në tabelën STM32VL Discovery, kemi mësuar të flasim, në gjuhën e programimit C, do të ishte koha për të krijuar një projekt në klasën e parë.

Shkrimi i programit

Pasi të keni përfunduar me krijimin dhe konfigurimin e projektit, mund të filloni të shkruani programin real. Siç është zakon për të gjithë programuesit, programi i parë i shkruar për të punuar në një kompjuter është një program që shfaq mbishkrimin "HelloWorld" në ekran dhe për të gjithë mikrokontrolluesit, programi i parë për mikrokontrolluesin pulson LED. Ne nuk do të bëjmë përjashtim nga kjo traditë dhe do të shkruajmë një program që do të kontrollojë LED-in LD3 në tabelën STM32VL Discovery.

Pas krijimit të një projekti bosh në IAR, ai krijon një kod programi minimal:

Tani programi ynë do të "rrotullohet" gjithmonë në një lak derisa.

Në mënyrë që ne të kontrollojmë LED-in, duhet të aktivizojmë klocking-un e portës me të cilën është lidhur dhe të vendosim pinin përkatës të portës së mikrokontrolluesit në dalje. Siç e diskutuam më herët në pjesën e parë, për lejimin e klockimit të portit ME përgjigjet pak IOPCEN regjistroheni RCC_APB2ENR. Sipas dokumentit " RM0041referencëmanual.pdf» për të aktivizuar kalimin e autobusit të portit ME kërkohet në regjistër RCC_APB2ENR vendos pak IOPCEN për njësi. Kështu që kur vendosim këtë bit, të mos rivendosim të tjerët në këtë regjistër, duhet të zbatojmë operacionin e mbledhjes logjike (logjike "OR") në gjendjen aktuale të regjistrit dhe më pas të shkruajmë vlerën që rezulton në përmbajtjen e regjistroheni. Në përputhje me strukturën e bibliotekës ST, qasja në vlerën e regjistrit për lexim dhe shkrim bëhet përmes një treguesi në strukturë. RCC-> APB2 ENR. Kështu, duke kujtuar materialin nga pjesa e dytë, mund të shkruajmë kodin e mëposhtëm që kryen një cilësim bit IOPCEN në regjistër RCC_APB2ENR:

Siç mund ta shihni, nga skedari "stm32f10x.h", vlera e bitit IOPCEN definuar si 0x00000010, që korrespondon me bitin e katërt ( IOPCEN) regjistroheni APB2ENR dhe përputhet me vlerën e specifikuar në fletën e të dhënave.

Tani le të vendosim daljen në të njëjtën mënyrë 9 port ME. Për ta bërë këtë, ne duhet të konfigurojmë këtë kunj porti që të dalë në modalitetin push-pull. Regjistri është përgjegjës për vendosjen e modalitetit të portit për hyrje / dalje GPIOC_CRH, ne e kemi konsideruar tashmë në , përshkrimi i tij është gjithashtu në seksionin "7.2.2 Regjistri i konfigurimit të portit të lartë" të fletës së të dhënave. Për të vendosur daljen në modalitetin e daljes me një shpejtësi maksimale prej 2 MHz, është e nevojshme në regjistër GPIOC_CRH instaloni MODI 9 në një dhe rivendosni bitin MODI 9 në zero. Bitët janë përgjegjës për vendosjen e mënyrës së funksionimit të daljes si funksionin kryesor me daljen push-tërheqëse. CNF9 dhe CNF9 , për të konfiguruar mënyrën e funksionimit që kërkojmë, të dy këta bit duhet të rivendosen në zero.

Tani kunja e portës me të cilën është lidhur LED është vendosur në dalje, për të kontrolluar LED-in, duhet të ndryshojmë gjendjen e pinit të portit duke vendosur daljen në një njësi logjike. Ka dy mënyra për të ndryshuar gjendjen e një pin porti, e para është të shkruani drejtpërdrejt në regjistrin e gjendjes së portit përmbajtjen e ndryshuar të regjistrit të portit, ashtu siç bëmë vendosjen e portit. Kjo metodë nuk rekomandohet duke pasur parasysh mundësinë e një situate në të cilën një vlerë e pasaktë mund të shkruhet në regjistrin e portit. Kjo situatë mund të ndodhë nëse gjatë një ndryshimi në gjendjen e regjistrit, nga momenti kur gjendja e regjistrit tashmë është lexuar dhe deri në momentin kur gjendja e ndryshuar është shkruar në regjistër, ndonjë pajisje periferike ose ndërprerje do të ndryshojë gjendjen e këtij porti. Pas përfundimit të operacionit për ndryshimin e gjendjes së regjistrit, vlera do të shkruhet në regjistër pa marrë parasysh ndryshimet që kanë ndodhur. Megjithëse probabiliteti i kësaj situate është shumë i ulët, ia vlen të përdoret një metodë tjetër në të cilën situata e përshkruar është e përjashtuar. Për ta bërë këtë, ekzistojnë dy regjistra në mikrokontrollues. GPIOx_BSRR dhe GPIOx_BRR. Kur shkruani një njësi logjike në bitin e kërkuar të regjistrit GPIOx_BRR kunja e portit përkatës do të rivendoset në zero logjike. Regjistrohu GPIOx_BSRR mund të vendosë dhe rivendosë gjendjen e kunjave të portit, për të vendosur pinin e portit në një logjik, duhet të vendosni bitet BSn, që korrespondon me numrin e bitit të kërkuar, këta bit ndodhen në regjistrat e poshtëm të bajtit. Për të rivendosur gjendjen e pinit të portit në zero logjike, duhet të shkruani bitet BRn kunjat përkatëse, këto bit janë të vendosura në pjesët e sipërme të regjistrit të portit.

LED LD3 i lidhur me daljen 9 port ME. Për të ndezur këtë LED, duhet të aplikojmë një njësi logjike në pinin përkatës të portës në mënyrë që të "ndizet" LED.

Le të shtojmë kodin për vendosjen e daljes së portit LED në programin tonë, dhe gjithashtu shtojmë një funksion të vonesës së softuerit për të zvogëluar frekuencën e ndërrimit të LED:

//Mos harroni të lidhni skedarin e kokës me një përshkrim të regjistrave të mikrokontrolluesit

#include "stm32f10x.h"

i pavlefshëm Vonesa ( i pavlefshëm);

i pavlefshëm Vonesa ( i pavlefshëm)
{
i panënshkruar gjatë i;
për(i=0; i<2000000; i++);
}

//Funksioni ynë kryesor

i pavlefshëm kryesore( i pavlefshëm)
{


RCC->APB2ENR |= RCC_APB2ENR_IOPCEN;

//pastro bit MODE9 (rivendos bit MODE9_1 dhe MODE9_0 në zero)
GPIOC->CRH &= ~GPIO_CRH_MODE9;

//Cakto bitin MODE9_1 për të vendosur daljen në një dalje me një shpejtësi prej 2 MHz
GPIOC->CRH |= GPIO_CRH_MODE9_1;

//pastroni bitet CNF (të vendosura si dalje për qëllime të përgjithshme, simetrike (shtytje-tërheqje))
GPIOC->CRH &= ~GPIO_CRH_CNF9;

derisa(1)
{

//Vendosja e pinit 9 të portës C në një logjike ("ndizet" LED)
GPIOC->BSRR = GPIO_BSRR_BS9;


vonesë ();


GPIOC->BSRR = GPIO_BSRR_BR9;


vonesë ();

}
}

Ju mund ta shkarkoni arkivin me kodin burimor të programit të shkruar duke përdorur kontrollin e drejtpërdrejtë të regjistrave të mikrokontrolluesit në lidhjen.

Programi ynë i parë i zbatueshëm u shkrua, kur e shkruanim, për të punuar dhe konfiguruar pajisjet periferike, ne përdorëm të dhëna nga fleta zyrtare e të dhënave " RM0041referencëmanual.pdf”, ky burim informacioni për regjistrat e mikrokontrolluesit është më i sakti, por për ta përdorur duhet të rilexoni shumë informacione, gjë që e ndërlikon shkrimin e programeve. Për të lehtësuar procesin e konfigurimit të pajisjeve periferike të mikrokontrolluesit, ekzistojnë gjeneratorë të ndryshëm kodi, mjeti zyrtar nga ST është Microxplorer, por ai është ende pak funksional dhe për këtë arsye, zhvilluesit e palëve të treta kanë krijuar një program alternativ "STM32 Gjeneruesi i kodit të programit » . Ky program ju lejon të merrni me lehtësi kodin e cilësimeve periferike duke përdorur një ndërfaqe grafike të përshtatshme dhe intuitive (shih Fig. 2).


Oriz. 2 Pamja e ekranit të gjeneratorit të kodit STM32

Siç mund ta shihni nga Figura 2, kodi i krijuar nga programi për vendosjen e daljes LED përputhet me kodin që kemi shkruar më parë.

Për të ekzekutuar programin e shkruar, pas përpilimit të kodit burimor, duhet të ngarkoni programin tonë në mikrokontrollues dhe të shihni se si funksionon.

Video e mënyrës së korrigjimit të programit ndezës LED

Video e programit të ndezjes LED në tabelën STM32VL Discovery

Biblioteka funksionon për të punuar me pajisjet periferike

Për të thjeshtuar punën me vendosjen e regjistrave të pajisjeve periferike të mikrokontrolluesve, ST ka zhvilluar biblioteka, falë përdorimit të të cilave, nuk është e nevojshme të lexohet aq mirë datasheet, sepse gjatë përdorimit të këtyre bibliotekave, puna e shkrimit të një programi do të bëhet më afër shkrimit të programeve të nivelit të lartë, pasi të gjitha funksionet e nivelit të ulët zbatohen në nivelin e funksioneve të bibliotekës. Sidoqoftë, nuk duhet të braktiset plotësisht përdorimi i punës së drejtpërdrejtë me regjistrat e mikrokontrolluesve, duke pasur parasysh faktin se funksionet e bibliotekës kërkojnë më shumë kohë procesori për ekzekutimin e tyre, si rezultat, përdorimi i tyre në seksionet kritike për kohën e programit nuk justifikohet. Por prapëseprapë, në shumicën e rasteve, gjëra të tilla si inicializimi periferik nuk janë kritike në kohën e ekzekutimit dhe komoditeti i përdorimit të funksioneve të bibliotekës është më i preferueshëm.

Tani le të shkruajmë programin tonë duke përdorur bibliotekën ST. Programi duhet të konfigurojë portet I / O, për të përdorur funksionet e bibliotekës për vendosjen e porteve, duhet të lidhni skedarin e kokës " stm32f10x_gpio.h» (shih tabelën 1). Ky skedar mund të lidhet duke hequr komentin e linjës përkatëse në skedarin e konfigurimit të kokës së lidhur " stm32f10x_conf.h". Në fund të dosjes stm32f10x_gpio.h» ekziston një listë e deklaratave të funksioneve për të punuar me portet. Një përshkrim i detajuar i të gjitha funksioneve të disponueshme mund të gjendet në skedar " stm32f10x_stdperiph_lib_um.chm”, një përshkrim i shkurtër i më të përdorurve është dhënë në tabelën 2.

Tabela 2. Përshkrimi i funksioneve kryesore të cilësimeve të portit

Funksioni

Përshkrimi i funksionit, parametrat e kaluar dhe të kthyer

GPIO_DeInit(
GPIO_TypeDef* GPIOx)

Vendos vlerat e regjistrave të konfigurimit të portit GPIOx në vlerat e paracaktuara

GPIO_Init(
GPIO_TypeDef* GPIOx,

Vendos regjistrat e konfigurimit të portit GPIOx sipas parametrave të specifikuar në strukturën GPIO_InitStruct

GPIO_StructInit(
GPIO_InitTypeDef* GPIO_InitStruct)

Plotëson të gjitha fushat e strukturës GPIO_InitStruct me vlerat e paracaktuara

uint8_t GPIO_ReadInputDataBit(
GPIO_TypeDef* GPIOx,
uint16_t GPIO_Pin);

Leximi i vlerës hyrëse të pinit GPIO_Pin të portës GPIOx

uint16_t GPIO_ReadInputData(
GPIO_TypeDef* GPIOx)

Lexoni vlerat hyrëse të të gjitha kunjave të portit GPIOx

GPIO_SetBits(
GPIO_TypeDef* GPIOx,
uint16_t GPIO_Pin)

Vendosja e vlerës së daljes së pinit GPIO_Pin të portës GPIOx në një vlerë logjike

GPIO_ResetBits(
GPIO_TypeDef* GPIOx,
uint16_t GPIO_Pin)

Rivendosja e vlerës së daljes së pinit GPIO_Pin të portës GPIOx në zero logjike

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

Shkruani vlerën BitVal në pinin GPIO_Pin të portës GPIOx

GPIO_Write(
GPIO_TypeDef* GPIOx,
uint16_t PortVal)

Shkruani vlerën PortVal në portin GPIOx

Siç mund të shihet nga përshkrimi i funksioneve, si parametra për cilësimet e portit, etj., jo shumë parametra të ndryshëm individualë i kalohen funksionit, por një strukturë. Strukturat janë të dhëna të grumbulluara që kanë një lidhje logjike. Ndryshe nga vargjet, strukturat mund të përmbajnë të dhëna të llojeve të ndryshme. Me fjalë të tjera, një strukturë përfaqëson një grup variablash të ndryshëm me lloje të ndryshme të kombinuara në një ndryshore unike. Variablat në këtë strukturë quhen fusha të strukturës dhe aksesohen si më poshtë: fillimisht shkruhet emri i strukturës, pastaj shkruhet një pikë dhe emri i fushës së strukturës (emri i ndryshores në këtë strukturë).

Lista e variablave të përfshirë në strukturat për funksionet e punës me portet përshkruhet në të njëjtin skedar pak më lart se përshkrimi i funksioneve. Kështu, për shembull, struktura GPIO_InitTypeDef"ka strukturën e mëposhtme:

typedef struct
{

uint16_t GPIO_Pin; /*!< Specifies the GPIO pins to be configured.
Ky parametër mund të jetë çdo vlerë e @ref GPIO_pins_define */

GPIOSpeed_TypeDef GPIO_Speed; /*!< Specifies the speed for the selected pins.
Ky parametër mund të jetë një vlerë prej @ref GPIOSpeed_TypeDef */

GPIOMode_TypeDef GPIO_Mode; /*!< Specifies the operating mode for the selected pins.
Ky parametër mund të jetë një vlerë prej @ref GPIOMode_TypeDef */

)GPIO_InitTypeDef;

Fusha e parë e kësaj strukture përmban variablin " GPIO_ Gjilpere» lloji e panënshkruar shkurt, në këtë variabël është e nevojshme të shkruhen flamujt e numrave të daljeve përkatëse për të cilat supozohet të bëhen cilësimet e nevojshme. Mund të konfiguroni disa dalje në të njëjtën kohë duke vendosur disa konstante si parametër përmes operatorit pjesërisht OSE(cm. ). Bitwise OR do të "mbledhë" të gjitha nga konstantat e listuara, dhe vetë konstantat janë një maskë, e destinuar vetëm për një përdorim të tillë. Përkufizimet makro të konstantave janë specifikuar në të njëjtin skedar më poshtë.

Fusha e dytë e strukturës " GPIO_InitTypeDef» cakton shpejtësinë maksimale të mundshme të daljes së portit. Lista e vlerave të mundshme për këtë fushë është renditur më sipër:

Përshkrimi i vlerave të mundshme:

  • GPIO_Mode_AIN- hyrje analoge (Anglisht Analog INput);
  • GPIO_Mode_IN_FLOATING- hyrje pa tërheqje, e varur (eng. Input float) në ajër
  • GPIO_Mode_IPD- tërheqje e hyrjes
  • GPIO_Mode_IPU- Tërheqja e hyrjes
  • GPIO_Mode_Out_OD- dalje me një kullim të hapur (Eng. Output Open Drain)
  • GPIO_Mode_Out_PP- dalje me dy gjendje (Anglisht Output Push-Pull - mbrapa dhe mbrapa)
  • GPIO_Mode_AF_OD- Hapni daljen e kullimit për Funksionin Alternativ. Përdoret në rastet kur dalja duhet të kontrollohet nga pajisjet periferike të bashkangjitura në këtë kunj porti (për shembull, kunja USART1 Tx, etj.)
  • GPIO_Mode_AF_PP- njësoj, por me dy gjendje

Në mënyrë të ngjashme, mund të shikoni strukturën e variablave të strukturave të tjera të nevojshme për të punuar me funksionet e bibliotekës.

Për të punuar me strukturat, ato, si variablat, duhet të deklarohen dhe t'u caktohet një emër unik, pas të cilit mund të hyni në fushat e strukturës së deklaruar me emrin që i është caktuar.

//Deklaroni strukturën

/*
Përpara se të filloni të plotësoni fushat e strukturës, rekomandohet të inicializoni përmbajtjen e strukturës me të dhënat e paracaktuara, kjo bëhet për të parandaluar shkrimin e të dhënave të pasakta nëse për ndonjë arsye nuk kanë të gjitha fushat e strukturës. është mbushur.

Për të kaluar vlerat e një strukture në një funksion, paraprini emrin e strukturës me simbolin &. Ky simbol i tregon përpiluesit se është e nevojshme të kalohen në funksion jo vlerat e përmbajtura në strukturë, por adresa e kujtesës ku ndodhen këto vlera. Kjo është bërë për të zvogëluar numrin e veprimeve të nevojshme të procesorit për të kopjuar përmbajtjen e strukturës, dhe gjithashtu kursen RAM. Kështu, në vend që të kalohen shumë bajtë të përmbajtur në strukturë tek funksioni, do të kalohet vetëm një, që përmban adresën e strukturës.
*/

/* Shkruani numrin e pinit të portit në fushën GPIO_Pin të strukturës GPIO_Init_struct, të cilën do ta konfigurojmë më tej */

GPIO_Init_struct.GPIO_Pin=GPIO_Pin_9;

/* Plotësoni fushën GPIO_Speed ​​në të njëjtën mënyrë */

/*
Pasi të kemi plotësuar fushat e kërkuara të strukturës, kjo strukturë duhet të kalojë në funksion, i cili do të bëjë hyrjen e nevojshme në regjistrat përkatës. Përveç strukturës me cilësimet për këtë funksion, është gjithashtu e nevojshme të kalohet emri i portit për të cilin synohen cilësimet.
*/

Pothuajse të gjitha pajisjet periferike janë konfiguruar afërsisht në të njëjtën mënyrë, ndryshimet janë vetëm në parametrat dhe komandat specifike për secilën pajisje.

Tani le të shkruajmë programin tonë ndezës LED duke përdorur vetëm funksionet e bibliotekës.

// Mos harroni të lidhni skedarin e kokës me një përshkrim të regjistrave të mikrokontrolluesit

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

//deklarimi i funksionit të vonesës së programit

i pavlefshëm Vonesa ( i pavlefshëm);

//Vetë funksioni i vonesës së softuerit

i pavlefshëm Vonesa ( i pavlefshëm)
{
i panënshkruar gjatë i;
për(i=0; i<2000000; i++);
}

//Funksioni ynë kryesor

i pavlefshëm kryesore( i pavlefshëm)
{

//Aktivizo klockimin e autobusit të portit C
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);

//Deklaroni një strukturë për të konfiguruar portin
GPIO_InitTypeDef GPIO_Init_struct;

//Mbush strukturën me vlera fillestare
GPIO_StructInit(&GPIO_Init_struct);

/* Shkruani numrin e pinit të portit në fushën GPIO_Pin të strukturës GPIO_Init_struct, të cilën do ta konfigurojmë më tej */
GPIO_Init_struct.GPIO_Pin = GPIO_Pin_9;

// Plotësoni fushat GPIO_Speed ​​dhe GPIO_Mode në mënyrë të ngjashme
GPIO_Init_struct.GPIO_Speed= GPIO_Speed_2MHz;
GPIO_Init_struct.GPIO_Mode = GPIO_Mode_Out_PP;

//Ne e kalojmë strukturën e kompletuar për të kryer veprime për vendosjen e regjistrave
GPIO_Init(GPIOC, &GPIO_Init_struct);

//Kyshi ynë kryesor i pafund
derisa(1)
{
//Vendosja e pinit 9 të portës C në një logjikë (LED "e ndezur")
GPIO_SetBits (GPIOC, GPIO_Pin_9);

// Shtoni një vonesë softueri në mënyrë që LED të ndizet për një kohë
vonesë ();

//Rivendosja e gjendjes së pinit 9 të portës C në zero logjike
GPIO_ResetBits (GPIOC, GPIO_Pin_9);

//Shtimi i vonesës së softuerit përsëri
vonesë ();
}
}

lidhje .

Nga shembulli i mësipërm, mund të shihet se përdorimi i funksioneve të bibliotekës për të punuar me pajisje periferike ju lejon të afroni programet e shkrimit për mikrokontrolluesin më afër programimit të orientuar nga objekti, dhe gjithashtu zvogëlon nevojën për qasje të shpeshtë në fletën e të dhënave për të lexuar përshkrimin të regjistrave të mikrokontrolluesit, por përdorimi i funksioneve të bibliotekës kërkon një njohuri më të lartë të gjuhës së programimit. Në funksion të kësaj, për njerëzit që nuk janë veçanërisht të njohur me programimin, një opsion më i thjeshtë për të shkruar programe do të jetë një mënyrë për të shkruar programe pa përdorur funksionet e bibliotekës, me akses të drejtpërdrejtë në regjistrat e mikrokontrolluesit. Për ata që e njohin mirë gjuhën e programimit, por nuk njohin mirë mikrokontrolluesit, veçanërisht STM32, përdorimi i funksioneve të bibliotekës thjeshton shumë procesin e shkrimit të programeve.

Kjo rrethanë, si dhe fakti që ST është kujdesur për një shkallë të lartë të përputhshmërisë, si në aspektin harduerik ashtu edhe në atë softuer, të mikrokontrolluesve të ndryshëm të tij, kontribuon në studimin më të lehtë të tyre, pasi nuk është e nevojshme të thellohen në veçoritë strukturore të kontrollues të ndryshëm.Seria STM32 dhe ju lejon të zgjidhni cilindo nga mikrokontrolluesit e disponueshëm në linjën STM32 si mikrokontrollues për studim.

Trajtuesi i ndërprerjeve

Mikrokontrolluesit kanë një aftësi të jashtëzakonshme - të ndalojnë ekzekutimin e programit kryesor në një ngjarje specifike dhe të vazhdojnë në ekzekutimin e një nënprogrami të veçantë - mbajtës i ndërprerjeve. Burimet e ndërprerjes mund të jenë ose ngjarje të jashtme - ndërprerje për marrjen / transmetimin e të dhënave përmes çdo ndërfaqeje të transferimit të të dhënave, ose një ndryshim në gjendjen e daljes, ose ato të brendshme - tejkalim i kohëmatësit, etj. Një listë e burimeve të mundshme të ndërprerjeve për mikrokontrolluesit e serisë STM32 është dhënë në fletën e të dhënave " Manuali i referencës RM0041"Në kapitull" 8 Ndërprerjet dhe ngjarjet».

Meqenëse mbajtësi i ndërprerjeve është gjithashtu një funksion, ai do të shkruhet si një funksion i rregullt, por në mënyrë që përpiluesi të dijë se ky funksion është një mbajtës specifik i ndërprerjeve, duhet të zgjidhen emrat e paracaktuar si emër të funksionit, tek i cili ridrejtohet vektori i ndërprerjes. janë të specifikuara. Lista e emrave të këtyre funksioneve me një përshkrim të shkurtër është në skedarin assembler " startup_stm32f10x_md_vl.s". Mund të ketë disa burime ndërprerjesh për një mbajtës të ndërprerjeve, për shembull, funksioni i mbajtësit të ndërprerjeve " USART1_IRQHandler» mund të thirret në rast të përfundimit të marrjes dhe përfundimit të transmetimit të një bajt, etj.

Për të filluar me ndërprerjet, duhet të konfiguroni dhe inicializoni kontrolluesin e ndërprerjeve NVIC. Në arkitekturën Cortex M3, çdo ndërprerje mund të vendoset në grupin e vet prioritar për rastet kur ndodhin ndërprerje të shumta në të njëjtën kohë. Pastaj duhet të konfiguroni burimin e ndërprerjes.

Fusha NVIC_IRQChannel tregon se cilin ndërprerje duam të konfigurojmë. Konstanta USART1_IRQn përcakton kanalin përgjegjës për ndërprerjet e lidhura me USART1. Përcaktohet në skedar stm32f10x.h”, konstante të tjera të ngjashme janë përcaktuar aty.

Dy fushat e ardhshme tregojnë përparësinë e ndërprerjeve (vlerat maksimale të këtyre dy parametrave përcaktohen nga grupi i përzgjedhur i përparësisë). Fusha e fundit, në fakt, përfshin përdorimin e ndërprerjeve.

Në funksion NVIC_Init, si dhe gjatë konfigurimit të porteve, një tregues në një strukturë transmetohet për të aplikuar cilësimet e bëra dhe për t'i shkruar ato në regjistrat përkatës të mikrokontrolluesit.

Tani, në cilësimet e modulit, duhet të vendosni parametrat me të cilët ky modul do të gjenerojë një ndërprerje. Së pari ju duhet të aktivizoni ndërprerjen, kjo bëhet duke thirrur funksionin emri_ITConfig(), i cili ndodhet në skedarin e kokës së pajisjes periferike.

// Aktivizo ndërprerjet në fund të transferimit të bajtit nëpërmjet USART1
USART_ITConfig(USART1, USART_IT_TXE, ENABLE);

// Aktivizo ndërprerjet në fund të marrjes së një bajt nga USART1
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);

Një përshkrim i parametrave të kaluar në funksion mund të gjendet në skedarin e kodit burimor të pajisjes periferike, pak mbi vendndodhjen e vetë funksionit. Ky funksion mundëson ose çaktivizon ndërprerjet në ngjarje të ndryshme nga moduli periferik i specifikuar. Kur ky funksion të ekzekutohet, mikrokontrolluesi do të jetë në gjendje të gjenerojë ndërprerje për ngjarjet që na duhen.

Pasi të futemi në funksionin e trajtimit të ndërprerjeve, duhet të kontrollojmë se cila ngjarje e ka shkaktuar ndërprerjen dhe më pas të rivendosim grupin e flamurit, përndryshe, me daljen nga ndërprerja, mikrokontrolluesi do të vendosë që ne nuk e kemi përpunuar ndërprerjen, pasi flamuri i ndërprerjes është ende i vendosur.

Për të kryer veprime të ndryshme, të vogla, të përsëritura me një periudhë të saktë, mikrokontrolluesit me një bërthamë Cortex-M3 kanë një kohëmatës të sistemit të krijuar posaçërisht për këtë. Funksioni i këtij kohëmatësi përfshin vetëm thirrjen e ndërprerjes në intervale kohore të specifikuara rreptësisht. Si rregull, në ndërprerjen e thirrur nga ky kohëmatës, vendoset kodi për të matur kohëzgjatjen e proceseve të ndryshme. Deklarata e funksionit të vendosjes së kohëmatësit ndodhet në skedar " bërthamë_ cm3. h". Argumenti i kaluar te funksioni specifikon numrin e cikleve të autobusit të sistemit ndërmjet intervaleve të thirrjeve të mbajtësit të ndërprerjeve të kohëmatësit të sistemit.

SysTick_Config(clk);

Tani, duke u marrë me ndërprerjet, ne do të rishkruajmë programin tonë, duke përdorur kohëmatësin e sistemit si një element të përcaktimit të kohës. Sepse timer SysTick”është një sistem dhe mund të përdoret nga blloqe të ndryshme funksionale të programit tonë, atëherë do të ishte e arsyeshme që funksioni i trajtimit të ndërprerjeve të zhvendosej nga kohëmatësi i sistemit në një skedar të veçantë, nga ky funksion i thirrjes së funksioneve për çdo bllok funksional veçmas.

Një shembull i skedarit "main.c" të programit për ndezjen e LED duke përdorur një ndërprerje:

//Lidhni skedarin e kokës me përshkrimin e regjistrave të mikrokontrolluesit

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

i panënshkruar ndër LED_timer;

//Funksioni i thirrur nga funksioni i mbajtësit të ndërprerjeve të kohëmatësit të sistemit

i pavlefshëm SysTick_Timer_main( i pavlefshëm)
{
//Nëse ndryshorja LED_timer nuk ka arritur ende 0,
nëse(LED_timer)
{
//Kontrolloni vlerën e tij, nëse është më shumë se 1500, ndizni LED
nëse(LED_timer>1500) GPIOC->BSRR= GPIO_BSRR_BS9;

//përndryshe, nëse më pak se ose e barabartë me 1500, atëherë çaktivizoni
tjetër GPIOC->BSRR= GPIO_BSRR_BR9;

//Le të zvogëlojmë variablin LED_timer
LED_timer--;
}

//Nëse vlera e ndryshores ka arritur zero, vendosni një vlerë të re prej 2000
tjetër LED_timer=2000;
}

//Funksioni ynë kryesor

i pavlefshëm kryesore( i pavlefshëm)
{

//Aktivizo klockimin e autobusit të portit C
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);

//Deklaroni një strukturë për të konfiguruar portin
GPIO_InitTypeDef GPIO_Init_struct;

//Mbush strukturën me vlera fillestare
GPIO_StructInit(&GPIO_Init_struct);

/* Shkruani numrin e pinit të portit në fushën GPIO_Pin të strukturës GPIO_Init_struct, të cilën do ta konfigurojmë më tej */
GPIO_Init_struct.GPIO_Pin = GPIO_Pin_9;

// Plotësoni fushat GPIO_Speed ​​dhe GPIO_Mode në mënyrë të ngjashme
GPIO_Init_struct.GPIO_Speed= GPIO_Speed_2MHz;
GPIO_Init_struct.GPIO_Mode = GPIO_Mode_Out_PP;

//Ne e kalojmë strukturën e kompletuar për të kryer veprime për vendosjen e regjistrave
GPIO_Init(GPIOC, &GPIO_Init_struct);

// zgjidhni grupin e përparësisë për ndërprerjet
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);

//Konfiguro funksionimin e kohëmatësit të sistemit me një interval prej 1ms
SysTick_Config (24000000/1000);

//Kyshi ynë kryesor i pafund
derisa(1)
{
// Këtë herë është bosh, i gjithë kontrolli LED ndodh me ndërprerje
}
}

Një pjesë e kodit burimor në skedarin "stm32f10x_it.c":


#include "main.h"

/**
* @brief Ky funksion trajton SysTick Handler.
* @paramAsnjë
* @retvalNone
*/

i pavlefshëm SysTick_Handler( i pavlefshëm)
{
SysTick_Timer_main();
}

Një shembull i një drafti funksional të programit për ndezjen e një LED duke përdorur një ndërprerje mund të shkarkohet nga lidhja.

Mbi këtë, historia ime në lidhje me bazat e zhvillimit të programeve për mikrokontrolluesin STM32 mund të konsiderohet e plotë. Unë kam dhënë të gjithë informacionin e nevojshëm për mundësinë e vetë-studimit të mëtejshëm të mikrokontrolluesve STM32. Materiali i ofruar është vetëm një fillestar, pasi një përshkrim i plotë i punës me mikrokontrolluesit nuk mund të përshkruhet brenda kornizës së asnjë artikulli. Përveç kësaj, studimi i mikrokontrolluesve pa fituar përvojë praktike është i pamundur, dhe përvoja reale vjen gradualisht me vite të tëra pune, eksperimente, me grumbullimin e zhvillimeve të ndryshme softuerike dhe harduerike, si dhe leximin e artikujve dhe dokumentacionit të ndryshëm për mikrokontrolluesit. Por mos lejoni që kjo t'ju trembë, sepse informacioni i dhënë në artikull është mjaft i mjaftueshëm për të krijuar pajisjen tuaj të parë në një mikrokontrollues, dhe ju mund të fitoni njohuri dhe përvojë të mëtejshme vetë, duke zhvilluar pajisje gjithnjë e më komplekse dhe më të mira çdo herë. dhe duke përmirësuar aftësitë tuaja.

Shpresoj se kam qenë në gjendje t'ju interesoj në studimin e mikrokontrolluesve dhe zhvillimin e pajisjeve bazuar në to, dhe puna ime do të jetë e dobishme dhe interesante për ju.

Kur krijoni aplikacionin e parë në mikrokontrolluesin STM32, ka disa mënyra për të shkuar. Së pari, ai klasik, marrim përshkrimin e saktë të kontrolluesit në faqen e internetit www.st.com, i cili shfaqet me emrin "Manual referencë" dhe lexojmë përshkrimin e regjistrave periferikë. Pastaj përpiqemi t'i shkruajmë dhe të shohim se si funksionojnë pajisjet periferike. Leximi i këtij dokumenti është shumë i dobishëm, por në fazën e parë të zotërimit të mikrokontrolluesit, kjo mund të braktiset, çuditërisht. Inxhinierët e STMicroelectronics kanë shkruar një bibliotekë standarde të drejtuesve të pajisjeve periferike. Për më tepër, ata kanë shkruar shumë shembuj të përdorimit të këtyre drejtuesve, të cilët mund të reduktojnë programimin e aplikacionit tuaj në shtypjen e tasteve Ctrl + C dhe Ctrl + V, e ndjekur nga një ndryshim i vogël në shembullin e drejtuesit për t'iu përshtatur nevojave tuaja. Kështu, lidhja e bibliotekës periferike të drejtuesve me projektin tuaj është metoda e dytë e ndërtimit të një aplikacioni. Përveç shpejtësisë së shkrimit, ka edhe avantazhe të tjera të kësaj metode: universaliteti i kodit dhe përdorimi i bibliotekave të tjera pronësore, si USB, Ethernet, kontrolli i diskut, etj., të cilat ofrohen në burime dhe përdorin një drejtues standard periferik. Ka edhe disavantazhe të kësaj metode: Aty ku mund t'ia dilni me një rresht kodi, drejtuesi standard periferik STM32 do të shkruajë 10. Vetë biblioteka periferike ofrohet gjithashtu si skedarë burimi, kështu që ju mund të gjurmoni se cilin pjesë e regjistrimit ose ai funksion ndryshon. Nëse dëshironi, do të jetë e mundur të kaloni nga metoda e dytë e shkrimit të një programi në të parën duke komentuar një pjesë të kodit që përdor bibliotekën standarde më vete, e cila kontrollon drejtpërdrejt regjistrin periferik. Si rezultat i një veprimi të tillë, ju do të fitoni shpejtësinë e kontrollit, sasinë e RAM-it dhe ROM-it dhe do të humbni në universalitetin e kodit. Në çdo rast, inxhinierët e Promelectronica rekomandojnë përdorimin e bibliotekës së pajisjeve periferike standarde të paktën në fazën e parë.

Vështirësitë më të mëdha e presin zhvilluesin kur lidh bibliotekën me projektin e tij. Nëse nuk dini si ta bëni këtë, mund të shpenzoni shumë kohë në këtë ngjarje, gjë që bie në kundërshtim me vetë idenë e përdorimit të një shoferi të gatshëm. Materiali i kushtohet lidhjes së bibliotekës standarde me çdo familje STM32.

Çdo familje STM32 ka bibliotekën e saj të pajisjeve periferike standarde. Kjo për faktin se vetë periferia është e ndryshme. Për shembull, pajisjet periferike të kontrollorëve STM32L kanë një funksion të kursimit të energjisë si një nga detyrat, i cili përfshin shtimin e funksioneve të kontrollit. Një shembull klasik është ADC, i cili në STM32L ka aftësinë për të fikur harduerin, në mungesë të një komande konvertimi për një kohë të gjatë - një nga pasojat e detyrës së kursimit të energjisë. Kontrollorët ADC të familjeve STM32F nuk e kanë një funksion të tillë. Në fakt, për shkak të pranisë së një ndryshimi harduerik në periferi, ne kemi biblioteka të ndryshme drejtuese. Përveç ndryshimit të dukshëm në funksionet e kontrolluesit, ka një përmirësim në pajisjet periferike. Pra, pajisjet periferike të kontrollorëve të familjeve që u lëshuan më vonë mund të jenë më të menduara dhe më të përshtatshme. Për shembull, pajisjet periferike të kontrollorëve STM32F1 dhe STM32F2 kanë dallime në kontroll. Sipas mendimit të autorit, menaxhimi i pajisjeve periferike STM32F2 është më i përshtatshëm. Dhe kjo është e kuptueshme pse: familja STM32F2 u lëshua më vonë dhe kjo i lejoi zhvilluesit të merrnin parasysh disa nga nuancat. Prandaj, për këto familje - bibliotekat individuale të kontrollit periferik. Ideja e sa më sipër është e thjeshtë: në faqen e mikrokontrolluesit që do të përdorni, ekziston një bibliotekë periferike e përshtatshme për të.

Pavarësisht ndryshimit të pajisjeve periferike në familje, shoferët fshehin 90% të dallimeve brenda vetes. Për shembull, funksioni akordues i ADC-së i përmendur më sipër duket i njëjtë për të gjitha familjet:

void ADC_Init (ADC_Nom, ADC_Param),

ku ADC_Nom është numri ADC në formën e ADC1, ADC2, ADC3, etj.

ADC_Param - treguesi i strukturës së të dhënave, si të konfiguroni ADC (nga çfarë të filloni, nga sa kanale të dixhitalizoni, nëse duhet bërë në mënyrë ciklike, etj.)

10% e dallimeve familjare, në këtë shembull, të cilat do të duhet të korrigjohen kur lëvizni nga një familje STM32 në tjetrën, janë të fshehura në strukturën ADC_Param. Në varësi të familjes, numri i fushave në këtë strukturë mund të jetë i ndryshëm. Pjesa e përgjithshme ka të njëjtën sintaksë. Kështu, transferimi i një aplikacioni për një familje STM32, i shkruar në bazë të bibliotekave standarde periferike, në një tjetër është shumë i thjeshtë. Përsa i përket universalizimit të zgjidhjeve të bazuara në mikrokontrollues, STMicroelectronics është e parezistueshme!

Pra, ne shkarkuam bibliotekën për STM32 të përdorur. Ç'pritet më tej? Më pas, duhet të krijojmë një projekt dhe të lidhim skedarët e kërkuar me të. Merrni parasysh krijimin e një projekti duke përdorur si shembull mjedisin e zhvillimit IAR Embedded Workbench. Ne fillojmë mjedisin e zhvillimit dhe shkojmë te skeda "Project", zgjedhim artikullin "Krijo projekt" për krijimin e projektit:

Në projektin e ri që shfaqet, futni cilësimet duke qëndruar pezull mbi emrin e projektit, duke shtypur butonin e djathtë të miut dhe duke zgjedhur "Opsionet" nga menyja rënëse:

Zonat e memories së RAM dhe ROM:

Kur klikoni butonin "Ruaj", mjedisi do të ofrojë për të shkruar një skedar të ri përshkrimi të kontrolluesit në dosjen e projektit. Autori rekomandon krijimin e një skedari individual *.icp për çdo projekt dhe ruajtjen e tij në dosjen e projektit.

Nëse do të korrigjoni projektin tuaj në qark, gjë që rekomandohet, atëherë shkruani llojin e korrigjuesit që do të përdorni:

Në skedën e korrigjuesit të zgjedhur, specifikoni ndërfaqen për lidhjen e korrigjuesit (në rastin tonë, ST-Link është zgjedhur) me kontrolluesin:



Tani e tutje, projekti ynë pa biblioteka është gati për t'u kompiluar dhe ngarkuar në kontrollues. Mjedise të tjera si Keil uVision4, Resonance Ride7, etj. do të duhet të ndjekin të njëjtat hapa.

Nëse shkruani rreshtin në skedarin main.c:

#include "stm32f10x.h" ose

#include "stm32f2xx.h" ose

#include "stm32f4xx.h" ose

#include "stm32l15x.h" ose

#include "stm32l10x.h" ose

#include "stm32f05x.h"

duke treguar vendndodhjen e këtij skedari, ose duke e kopjuar këtë skedar në dosjen e projektit, atëherë disa zona memorie do të shoqërohen me regjistrat periferikë të familjes përkatëse. Vetë skedari ndodhet në dosjen e bibliotekës standarde të pajisjeve periferike në seksionin: \CMSIS\CM3\DeviceSupport\ST\STM32F10x (ose emri i ngjashëm për familjet e tjera). Tani e tutje, ju zëvendësoni adresën e regjistrit periferik si numër me emrin e saj. Edhe nëse nuk do të përdorni funksionet e bibliotekës standarde, rekomandohet të bëni një lidhje të tillë.

Nëse do të përdorni ndërprerje në projektin tuaj, rekomandohet të përfshini një skedar fillestar me shtesën *.s, i cili ndodhet përgjatë shtegut \CMSIS\CM3\DeviceSupport\ST\STM32F10x\startup\iar, ose të ngjashme, për familjet e tjera. Është e rëndësishme të theksohet se çdo mjedis ka skedarin e vet. Prandaj, nëse përdorim IAR EWB, duhet të marrim skedarin nga dosja IAR. Kjo është për shkak të një ndryshimi të vogël në sintaksën e mjediseve. Prandaj, në mënyrë që projekti të fillojë menjëherë, inxhinierët e STMicroelectronics shkruan disa variante të skedarëve fillestarë për disa nga mjediset më të njohura të zhvillimit. Shumica e familjeve STM32 kanë një skedar. Familja STM32F1 ka disa skedarë fillestarë:

  • startup_stm32f10x_cl.s - për mikrokontrolluesit STM32F105/107
  • startup_stm32f10x_xl.s - për mikrokontrolluesit STM32F101/STM32F103 768 kb ose më shumë
  • startup_stm32f10x_hd.s - për mikrokontrolluesit STM32F101/STM32F103 me memorie flash 256-512 kb
  • startup_stm32f10x_md.s - për mikrokontrolluesit STM32F101/ STM32F102/STM32F103 me memorie flash 64-128 kb
  • startup_stm32f10x_ld.s - për mikrokontrolluesit STM32F101/ STM32F102/STM32F103 me memorie flash më pak se 64 kb
  • startup_stm32f10x_hd_vl.s për mikrokontrolluesit STM32F100 me memorie flash 256-512 kb
  • startup_stm32f10x_md_vl.s për mikrokontrolluesit STM32F100 me memorie flash 64-128 kb
  • startup_stm32f10x_ld_vl.s për mikrokontrolluesit STM32F100 me memorie flash 32 kb ose më pak

Pra, në varësi të familjes, nënfamiljes dhe mjedisit të zhvillimit, shtoni skedarin e nisjes në projekt:

Këtu përfundon mikrokontrolluesi kur fillon programi. Ndërprerja thërret në mënyrë sekuenciale funksionin SystemInit() dhe më pas __iar_program_start. Funksioni i dytë rivendos ose shkruan vlerat e paracaktuara të variablave globale, pas së cilës kalon në programin e përdoruesit kryesor (). Funksioni SystemInit() konfiguron orën e mikrokontrolluesit. Është ajo që u përgjigjet pyetjeve:

  • A duhet të kaloj në kristal të jashtëm (HSE)?
  • Si të shumëzoni frekuencën nga HSI/HSE?
  • A kërkohet të lidhni radhën e shkarkimit të komandës?
  • Çfarë vonese kërkohet gjatë ngarkimit të një komande (për shkak të shpejtësisë së ulët të memories Flash)
  • Si të ndahet kronologjia e autobusëve periferikë?
  • A duhet të vendoset kodi në RAM të jashtëm?

Funksioni SystemInit() mund të shkruhet manualisht në projektin tuaj. Nëse e lëshoni këtë funksion si bosh, atëherë kontrolluesi do të punojë në një gjenerator të brendshëm RC me një frekuencë prej rreth 8 MHz (në varësi të llojit të familjes). Opsioni 2 - lidhni skedarin system_stm32f10x.c me projektin (ose emri i ngjashëm në varësi të llojit të familjes së përdorur), i cili ndodhet në bibliotekë përgjatë shtegut: Libraries\CMSIS\CM3\DeviceSupport\ST\STM32F10x. Ky skedar përmban funksionin SystemInit(). Kushtojini vëmendje frekuencës së kristalit të jashtëm HSE_VALUE. Ky parametër vendoset në skedarin e titullit stm32f10x.h. Vlera standarde është 8 dhe 25 MHz, në varësi të familjes STM32. Detyra kryesore e funksionit SystemInit () është të kalojë orën në një kuarc të jashtëm dhe të shumëzojë këtë frekuencë në një mënyrë të caktuar. Çfarë ndodh nëse vlera e HSE_VALUE është 8 MHz, bërthama duhet të jetë e klockuar në 72 MHz, dhe në fakt bordi ka një kuarc 16 MHz? Si rezultat i veprimeve të tilla të pasakta, bërthama do të marrë një frekuencë 144 MHz, e cila mund të jetë përtej funksionimit të garantuar të sistemit në STM32. ato. kur përfshini skedarin system_stm32f10x.c, do t'ju duhet të specifikoni vlerën HSE_VALUE. E gjithë kjo do të thotë që skedarët system_stm32f10x.c, system_stm32f10x.h dhe stm32f10x.h (ose emra të ngjashëm për familjet e tjera) duhet të jenë individuale për çdo projekt. DHE

Inxhinierët e STMicroelectronics kanë krijuar mjetin e konfigurimit të orës, i cili ju lejon të konfiguroni saktë orën e sistemit. Ky është një skedar Excel që gjeneron një skedar system_stm32xxx.c (i ngjashëm në emër me një familje të caktuar familjesh) pas vendosjes së parametrave të hyrjes dhe daljes së sistemit. Konsideroni punën e tij në shembullin e familjes STM32F4.

Opsionet: oshilator i brendshëm RC, oshilator i brendshëm RC me shumëzim frekuence ose kristal i jashtëm me shumëzim frekuence. Pas zgjedhjes së burimit të orës, futim parametrat e konfigurimit të dëshiruar të sistemit, si frekuenca e hyrjes (kur përdoret kuarci i jashtëm), frekuenca e orës bazë, pjesëtuesit e frekuencës së orës së autobusëve periferikë, funksionimi i tamponit të tërheqjes së instruksioneve, dhe të tjerët. Duke klikuar në butonin "Generate", ne kemi një dritare


Lidhja e skedarit system_stm32f4xx.c dhe analogëve të tij do të kërkojë lidhjen e një skedari tjetër të bibliotekës standarde periferike. Për të kontrolluar orën, ekziston një grup i tërë funksionesh që thirren nga skedari system_stm32xxxxxx.c. Këto funksione janë të vendosura në skedarin stm32f10x_rcc.c dhe kokën e tij. Prandaj, kur lidhni skedarin system_stm32xxxxxx.c me projektin, kërkohet të lidhni stm32f10x_rcc.c, përndryshe lidhësi i mjedisit do të raportojë mungesën e një përshkrimi funksioni me emrin RCC_xxxxxxx. Skedari i specifikuar ndodhet në bibliotekën periferike përgjatë shtegut: Libraries\STM32F10x_StdPeriph_Driver\src dhe titulli i tij \Libraries\STM32F10x_StdPeriph_Driver\inc.

Skedarët e kokës së drejtuesit periferik janë të lidhur në skedarin stm32f10x_conf.h, i cili referohet nga stm32f10x.h. Skedari stm32f10x_conf.h është thjesht një grup skedarësh të kokës së drejtuesit për pajisje periferike të kontrolluesit që do të përfshihen në projekt. Fillimisht, të gjitha titujt "#include" janë shënuar si komente. Lidhja e skedarit të kokës së periferisë konsiston në heqjen e komentit nga emri i skedarit përkatës. Në rastin tonë, kjo është linja #include "stm32f10x_rcc.h". Natyrisht, skedari stm32f10x_conf.h është individual për çdo projekt, sepse projekte të ndryshme përdorin pajisje të ndryshme periferike.

Dhe e fundit. Ju duhet të specifikoni disa direktiva për paraprocesorin e përpiluesit dhe shtigjet drejt skedarëve të kokës.



Rrugët drejt skedarëve të kokës mund të jenë të ndryshme, në varësi të vendndodhjes së bibliotekës periferike në lidhje me dosjen e projektit, por prania e "USE_STDPERIPH_DRIVER" është e detyrueshme kur lidhni drejtuesit standardë periferikë të bibliotekës.

Pra, ne kemi lidhur bibliotekën standarde me projektin. Për më tepër, ne kemi lidhur një nga drejtuesit standardë periferikë me projektin që kontrollon orën e sistemit.

Ne kemi mësuar se si duket pajisja e bibliotekës nga brenda, tani disa fjalë se si duket nga jashtë.



Kështu, përfshirja e skedarit të kokës stm32f10x.h në një aplikacion kërkon përfshirjen e skedarëve të tjerë të kokës dhe skedarëve të kodit. Disa nga ato të paraqitura në figurë janë përshkruar më sipër. Disa fjalë për pjesën tjetër. Skedarët STM32F10x_PPP.x janë skedarë drejtues periferikë. Një shembull i lidhjes së një skedari të tillë është treguar më lart, ky është RCC - periferia e kontrollit të orës së sistemit. Nëse duam të lidhim drejtuesit e pajisjeve të tjera periferike, atëherë emri i skedarëve të lidhur merret duke zëvendësuar "PPP" me emrin e pajisjes periferike, për shembull, ADC - STM32F10x_ADC.s, ose portet I / O STM32F10x_GPIO.s, ose DAC - STM32F10x_DAC.s. Në përgjithësi, është intuitivisht e qartë se cili skedar duhet të lidhet kur lidhni një pajisje periferike të caktuar. Skedarët "misc.c", "misc.h" janë në përgjithësi të njëjtat STM32F10x_PPP.x, ata kontrollojnë vetëm kernelin. Për shembull, konfigurimi i vektorëve të ndërprerjes, i cili është i integruar në kernel, ose menaxhimi i kohëmatësit SysTick, i cili është pjesë e kernelit. Skedarët xxxxxxx_it.c përshkruajnë vektorët NMI të kontrolluesit. Ato mund të plotësohen me vektorë të ndërprerjeve periferike. Skedari core_m3.h përshkruan bërthamën CortexM3. Kjo bërthamë është e standardizuar dhe mund të gjendet në mikrokontrolluesit e prodhuesve të tjerë. Për universalizimin ndër-platformë, STMicroelectronics punoi për të krijuar një bibliotekë të veçantë bërthamore CortexM, pas së cilës ARM e standardizoi atë dhe ia shpërndau prodhuesve të tjerë të mikrokontrolluesve. Kështu që kalimi në STM32 nga kontrollorët nga prodhuesit e tjerë me një bërthamë CortexM do të jetë pak më i lehtë.

Pra, ne mund të lidhim bibliotekën standarde periferike me çdo familje STM32. Ai që ka mësuar ta bëjë këtë është duke pritur për një çmim: një programim shumë të thjeshtë të mikrokontrolluesve. Biblioteka, përveç drejtuesve në formën e skedarëve burimor, përmban shumë shembuj të përdorimit të pajisjeve periferike. Si shembull, merrni parasysh krijimin e një projekti që përfshin rezultatet e krahasimit të kohëmatësit. Me qasjen tradicionale, ne do të studiojmë me kujdes përshkrimin e regjistrave të kësaj pajisjeje periferike. Por tani mund të studiojmë tekstin e programit të ekzekutimit. Ne hyjmë në dosjen e shembujve të pajisjeve periferike standarde, e cila ndodhet përgjatë shtegut ProjectSTM32F10x_StdPeriph_Examples. Këtu janë dosjet e shembujve me emrin e pajisjeve periferike të përdorura. Shkojmë te dosja "TIM". Kohëmatësit në STM32 kanë shumë funksione dhe cilësime, kështu që është e pamundur të demonstrohen aftësitë e kontrolluesit me një shembull. Prandaj, brenda drejtorisë së specifikuar, ka shumë shembuj të përdorimit të kohëmatësve. Ne jemi të interesuar në gjenerimin e një sinjali PWM nga një kohëmatës. Shkojmë te dosja "7PWM_Output". Brenda ka një përshkrim të programit në anglisht dhe një grup skedarësh:

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

Nëse projekti nuk ka ndërprerje, atëherë përmbajtja ndodhet tërësisht në skedarin main.c. Kopjoni këto skedarë në drejtorinë e projektit. Pas përpilimit të projektit, do të marrim një program për STM32, i cili do të konfigurojë kohëmatësin dhe portat I/O për të gjeneruar 7 sinjale PWM nga kohëmatësi 1. Më pas, mund të përshtatim kodin e shkruar tashmë në detyrën tonë. Për shembull, zvogëloni numrin e sinjaleve PWM, ndryshoni ciklin e punës, drejtimin e numërimit, etj. Funksionet dhe parametrat e tyre janë përshkruar mirë në skedarin stm32f10x_stdperiph_lib_um.chm. Emrat e funksioneve dhe parametrat e tyre lidhen lehtësisht me qëllimin e tyre për ata që dinë pak anglisht. Për qartësi, këtu është një pjesë e kodit të shembullit të marrë:

/* Konfigurimi i bazës kohore */ TIM_TimeBaseStructure.TIM_Prescaler = 0; // nuk ka parashkallëzues të impulseve numërues (regjistër 16-bitësh) TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; // duke numëruar drejtimin lart TIM_TimeBaseStructure.TIM_Period = TimerPeriod; // numëro deri në vlerën e TimerPeriod (konstante në program) TIM_TimeBaseStructure.TIM_ClockDivision = 0; // nuk ka para-ndarje të numëruesve TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; // numëruesi i tejmbushjes për gjenerimin e ngjarjeve (nuk përdoret në program) TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); // futja e vlerave të TimeBaseStructure në regjistrat e kohëmatësit 1 (futja e të dhënave për këtë variabël // është më lart) /* Konfigurimi i kanalit 1, 2,3 dhe 4 në modalitetin PWM */ // konfigurimi i daljeve PWM TIM_OCInitStructure.TIM_OCMode = TIMWMOC2_ ; // Mënyra e funksionimit PWM2 TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; // aktivizoni daljen e sinjaleve të kohëmatësit PWM TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable; // aktivizoni daljen plotësuese të kohëmatësit PWM TIM_OCInitStructure.TIM_Pulse = Channel1Pulse; // gjerësia e pulsit Channel1Pulsi është një konstante në programin TIM_OCInitStructure.TIM_OCPolariteti = TIM_OCPolariteti_I ulët; // vendosja e polaritetit të daljes TIM_OCInitStructure TIM_OCNPolariteti = TIM_OCNPolariteti_I lartë; // vendosja e polaritetit të daljes plotësuese TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set; // vendos gjendjen e sigurt të daljes PWM TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset; // vendos gjendjen e sigurt të daljes PWM plotësuese TIM_OC1Init(TIM1, &TIM_OCInitStructure); // futni vlerat e ndryshores TIM_OCInitStructure në regjistrat PWM të kanalit 1 // të timer1 TIM_OCInitStructure.TIM_Pulse = Channel2Pulse; // ndryshoni gjerësinë e pulsit në variablin OCInitStructure dhe futeni atë në TIM_OC2Init(TIM1, &TIM_OCInitStructure); // timer1 kanali 2 PWM regjistrat TIM_OCInitStructure.TIM_Pulse = Channel3Pulse; // ndryshoni gjerësinë e pulsit në variablin OCInitStructure dhe futeni atë në TIM_OC3Init(TIM1, &TIM_OCInitStructure); // timer1 kanali 3 PWM regjistrat TIM_OCInitStructure.TIM_Pulse = Channel4Pulse; // ndryshoni gjerësinë e pulsit në variablin OCInitStructure dhe futeni atë në TIM_OC4Init(TIM1, &TIM_OCInitStructure); // timer1 kanal 4 regjistrat PWM /* numëruesi TIM1 aktivizon */ TIM_Cmd(TIM1, ENABLE); // start timer1 /* TIM1 Dalja kryesore Aktivizo */ TIM_CtrlPWMOoutputs(TIM1, ENABLE); // aktivizoni rezultatet e krahasimit të kohëmatësit 1

Në anën e djathtë, autori la një koment në Rusisht për secilën rresht të programit. Nëse hapim të njëjtin shembull në përshkrimin e funksioneve të bibliotekave stm32f10x_stdperiph_lib_um.chm, do të shohim që të gjithë parametrat e funksionit të përdorur kanë një lidhje me përshkrimin e tyre, ku do të tregohen vlerat e tyre të mundshme. Vetë funksionet kanë gjithashtu një lidhje me përshkrimin dhe kodin e tyre burimor. Kjo është shumë e dobishme sepse Duke ditur se çfarë bën funksioni, ne mund të gjurmojmë se si e bën atë, cilat pjesë të regjistrave periferikë dhe si ndikon. Ky është, së pari, një burim tjetër informacioni për zotërimin e kontrolluesit, bazuar në përdorimin praktik të kontrolluesit. ato. ju së pari zgjidhni problemin teknik, dhe më pas studioni vetë zgjidhjen. Së dyti, kjo është një fushë për optimizimin e programit për ata që nuk janë të kënaqur me bibliotekën për sa i përket shpejtësisë dhe madhësisë së kodit.



Theksova se biblioteka standarde është e lidhur me sistemin. Në fakt, CMSIS është i lidhur - një sistem i përgjithësuar i përfaqësimit strukturor për MK, si dhe SPL - një bibliotekë standarde periferike. Le të shqyrtojmë secilën prej tyre:

CMSIS
Është një grup skedarësh me kokë dhe një grup i vogël kodesh për unifikimin dhe strukturimin e punës me thelbin dhe pajisjet periferike të MK. Në fakt, pa këto skedarë është e pamundur të punosh normalisht me MK. Bibliotekën mund ta merrni në faqen për MK.
Kjo bibliotekë, sipas përshkrimit, u krijua për të unifikuar ndërfaqet kur punoni me çdo MK të familjes Cortex. Megjithatë, në realitet, rezulton se kjo është e vërtetë vetëm për një prodhues, d.m.th. duke kaluar te mikrokontrolluesi i një kompanie tjetër, detyrohesh të studiosh periferinë e tij pothuajse nga e para.
Edhe pse ato skedarë që lidhen me bërthamën e procesorit MK janë identike për të gjithë prodhuesit (nëse vetëm sepse kanë një model të bërthamës së procesorit - të ofruar në formën e blloqeve ip nga ARM).
Prandaj, puna me pjesë të tilla të kernelit si regjistrat, udhëzimet, ndërprerjet dhe blloqet e bashkëprocesorit është standarde për të gjithë.
Sa për pajisjet periferike, STM32 dhe STM8 (papritmas) janë pothuajse të ngjashme, dhe kjo është pjesërisht e vërtetë edhe për MK-të e tjera të lëshuara nga ST. Në pjesën praktike, unë do të tregoj se sa e lehtë është përdorimi i CMSIS. Sidoqoftë, vështirësitë në përdorimin e tij shoqërohen me hezitimin e njerëzve për të lexuar dokumentacionin dhe për të kuptuar pajisjen MK.

SPL
Standard Peripheral Library - bibliotekë standarde periferike. Siç nënkupton edhe emri, qëllimi i kësaj biblioteke është të krijojë një abstraksion për periferinë MK. Biblioteka përbëhet nga skedarë të kokës ku deklarohen konstante të kuptueshme për njeriun për konfigurimin dhe punën me pajisjet periferike MK, si dhe skedarët e kodit burimor të mbledhur në vetë bibliotekën për operacionet me pajisjet periferike.
SPL është një abstraksion mbi CMSIS, duke i paraqitur përdoruesit një ndërfaqe të përbashkët për të gjitha MK-të, jo vetëm nga një prodhues, por në përgjithësi për të gjitha MK-të me një bërthamë procesori Cortex-Mxx.
Besohet se është më i përshtatshëm për fillestarët, sepse. ju lejon të mos mendoni se si funksionojnë pajisjet periferike, megjithatë, cilësia e kodit, universaliteti i qasjes dhe ngurtësia e ndërfaqeve vendosin kufizime të caktuara për zhvilluesin.
Gjithashtu, funksionaliteti i bibliotekës nuk ju lejon gjithmonë të zbatoni me saktësi konfigurimin e disa komponentëve si USART (Universal Synchronous-Asynchronous Serial Port) në kushte të caktuara. Në pjesën praktike do të përshkruaj edhe mënyrën e punës me këtë pjesë të bibliotekës.

Pershendetje te gjitheve. Siç e mbani mend, në artikullin e fundit ne konfiguruam paketën e softuerit për të punuar me mikrokontrolluesit STM32 dhe përpiluam programin e parë. Në këtë postim do të njihemi me arkitekturën e këtij bordi, mikrokontrolluesin dhe bibliotekat e disponueshme për punë.

Më poshtë është një vizatim i tabelës Zbulimi STM32F3 , ku: 1 — Sensori MEMS. Xhiroskop dixhital me 3 boshte L3GD20. 2 - Sistemi MEMS-në-një rast, që përmban një përshpejtues linear dixhital me 3 boshte dhe një sensor gjeomagnetik dixhital me 3 boshte LSM303DLHC. 4 - LD1 (PWR) - furnizimi me energji elektrike 3.3V. 5 - LD2 - LED e kuqe / jeshile. Parazgjedhja është e kuqe. E gjelbër do të thotë komunikim midis ST-LINK/v2 (ose V2-B) dhe PC. Kam ST-LINK/v2-B si dhe treguesin e portës me porosi USB. 6. -LD3/10 (e kuqe), LD4/9 (blu), LD5/8 (portokalli) dhe LD6/7 (jeshile). Në hyrjen e fundit, ju dhe unë ndezëm LED LD4. 7. - Dy butona: USER dhe RESET. 8. - USER USB me lidhës Mini-B.

9 - Debuger / programues USB ST-LINK/V2. një 0. - Mikrokontrollues STM32F303VCT6. 11. - Gjenerator i jashtëm me frekuencë të lartë 8 MHz. 12. - Këtu duhet të ketë një gjenerator me frekuencë të ulët, për fat të keq jo të salduar. 13. - SWD - ndërfaqe. 14. - Kërcuesit për zgjedhjen e programimit të kontrollorëve të jashtëm ose të brendshëm, në rastin e parë, duhet të hiqen. 15 - Jumper JP3 - bluzë, e krijuar për të lidhur një ampermetër për të matur konsumin e kontrolluesit. Është e qartë se nëse hiqet, atëherë guraleca jonë nuk do të fillojë. 16. - STM32F103C8T6 ka një tabelë korrigjimi. 17. - LD3985M33R Rregullator me rënie tensioni të ulët dhe nivel zhurme, 150mA, 3.3V.

Tani le të hedhim një vështrim më të afërt në arkitekturën e mikrokontrolluesit STM32F303VCT6. Karakteristikat teknike të tij: paketa LQFP-100, bërthama ARM Cortex-M4, frekuenca maksimale e bërthamës 72 MHz, madhësia e memories programore 256 KB, lloji i memories së programit FLASH, SRAM RAM 40 KB, RAM 8 KB, numri i hyrjeve/daljeve 87, ndërfaqet ( CAN, I²C, IrDA, LIN, SPI, UART/USART, USB), pajisjet periferike (DMA, I2S, POR, PWM, WDT), ADC/DAC 4*12 bit/2*12bit, tensioni i furnizimit 2...3.6 V , temperatura e punës -40 ...... +85 C. Në figurën e mëposhtme, pinout, ku shohim 87 porte I/O, 45 prej tyre Normal I/Os (TC, TTa), 42 tolerante 5 volt. I / Os (FT, FTf) - i pajtueshëm me 5 V. (në tabelë në kunjat e djathta 5V, në të majtë 3.3V). Çdo linjë I/O dixhitale mund të funksionojë si një linjë e përbashkët I/O.
destinacion ose funksion alternativ. Me përparimin e projekteve, ne do të njihemi vazhdimisht me periferinë.

Merrni parasysh bllok diagramin më poshtë. Zemra është një bërthamë 32-bit ARM Cortex-M4 që funksionon deri në 72 MHz. Ka një njësi të integruar të pikës lundruese FPU dhe një njësi të mbrojtjes së memories MPU, qeliza makro të integruara të gjurmës - Embedded Trace Macrocell (ETM), të cilat mund të përdoren për të monitoruar procesin e ekzekutimit të programit kryesor brenda mikrokontrolluesit. Ata janë në gjendje t'i nxjerrin këto vëzhgime vazhdimisht përmes kontakteve ETM për sa kohë që pajisja është në funksion. NVIC (Kontrolluesi i ndërprerjeve me vektor të ndërlidhur) - moduli i kontrollit të ndërprerjes. TPIU (Trace Port Interface Unit). Përmban memorie FLASH – 256 KB, SRAM 40 KB, RAM 8 KB. Midis bërthamës dhe kujtesës është një matricë Bus (Matrica e autobusit), e cila ju lejon të lidhni drejtpërdrejt pajisjet. Këtu shohim gjithashtu dy lloje të matricës së autobusit AHB dhe APB, ku i pari është më produktiv dhe përdoret për të lidhur komponentët e brendshëm me shpejtësi të lartë, dhe i fundit për pajisjet periferike (pajisjet I/O). Kontrolluesi ka 4 ADC 12-bit (ADC) (5 Mbps) dhe një sensor të temperaturës, 7 krahasues (GP Comparator1 ... 7), 4 amplifikatorë operacionalë të programueshëm (OpAmp1 ... 4) (PGA (Programmable Gain Array)) , 2 kanale 12-bitësh DAC (DAC), RTC (orë në kohë reale), dy kohëmatës vëzhgues - të pavarur dhe me dritare (WinWatchdog dhe Ind. WDG32K), 17 kohëmatës për qëllime të përgjithshme dhe shumëfunksionale.

Në terma të përgjithshëm, ne kemi marrë parasysh arkitekturën e kontrolluesit. Tani merrni parasysh bibliotekat e disponueshme të softuerit. Pas rishikimit, mund të dallohen: CMSIS, SPL dhe HAL. Konsideroni secilin aplikim në një shembull të thjeshtë të ndezjes së një LED.

1). CMSIS(Cortex Microcontroller Software Interface Standard) është biblioteka standarde për Cortex®-M. Ofron mbështetje për pajisjen dhe thjeshton ndërfaqet programuese. CMSIS ofron ndërfaqe të qëndrueshme dhe të thjeshta për kernelin, pajisjet e tij periferike dhe sistemet operative në kohë reale. Përdorimi i tij është një mënyrë profesionale e të shkruarit të programeve, sepse përfshin shkrimin e drejtpërdrejtë në regjistra dhe, në përputhje me rrethanat, është i nevojshëm leximi dhe studimi i vazhdueshëm i fletëve të të dhënave. Prodhuesi i pajisjeve të pavarura.
CMSIS përfshin komponentët e mëposhtëm:
- CMSIS-CORE: Nisja e vazhdueshme e sistemit dhe aksesi periferik (Fillimi i vazhdueshëm i sistemit dhe aksesi periferik);
- CMSIS-RTOS: Deterministic Real-Time Software Execution (Deterministic Real-Time Software Execution);
- CMSIS-DSP: Implementimi i shpejtë i procesimit të sinjalit dixhital (Fast Implementation of Digital signal processing);
- CMSIS-Driver: Ndërfaqet e përgjithshme periferike për programin e mesëm dhe kodin e aplikacionit (ndërfaqet e zakonshme periferike për programin e mesëm dhe kodin e aplikacionit);
- CMSIS-Pack: Qasje e lehtë në komponentët e softuerit të ripërdorshëm (Qasje e lehtë në komponentët e softuerit të ripërdorshëm);
- CMSIS-SVD: Pamje konsistente ndaj pajisjes dhe pajisjeve periferike (Pamje konsistente e pajisjes dhe pajisjeve periferike);
- CMSIS-DAP: Lidhja me harduerin e vlerësimit me kosto të ulët. Softuer për korrigjimin e gabimeve.

Për shembull, le të shkruajmë një program - ndezim një LED. Për ta bërë këtë, ne kemi nevojë për dokumentacion që përshkruan regjistrat. Në rastin tim Manuali i referencës RM0316 STM32F303xB/C/D/E, STM32F303x6/8, STM32F328x8, STM32F358xC, STM32F398xE MCU të avancuara të bazuara në ARM®, si dhe një përshkrim i këmbës specifike për të cilën është përgjegjës DS9118: Cortex®-M4 32b MCU+FPU me bazë ARM®, deri në 256 KB Flash+ 48 KB SRAM, 4 ADC, 2 ch. DAC, 7 komp, 4 PGA, kohëmatës, 2,0-3,6 V. Për të filluar, ne do të kalojmë portin në program, sepse. Si parazgjedhje, gjithçka është e çaktivizuar, gjë që rezulton në konsum të reduktuar të energjisë. Hapni manualin e referencës dhe shikoni seksionin "Rivendosja dhe kontrolli i orës", më pas harta e regjistrimit të RCC dhe shikoni se cili regjistër është përgjegjës për aktivizimin e IOPEEN

Le të kalojmë në përshkrimin e klockimit të periferisë së këtij regjistri Regjistri i aktivizimit të orës periferike AHB (RCC_AHBENR), ku shohim se ky port është nën bitin e 21-të. Aktivizo RCC->AHBENR|=(1<<21) . Далее сконфигурируем регистры GPIO. Нас интересует три: GPIOE_MODER и GPIOx_ODR . C помощью них повторим программу с предыдущей статьи, затактируем PE8. Первый отвечает за конфигурацию входа выхода, выбираем 01: General purpose output mode. GPIOE->MODER|=0×10000 . E dyta për përfshirjen e një niveli të ulët / të lartë në këmbë. Më poshtë është programi:

#include "stm32f3xx.h " // Skedari i kokës së mikrokontrolluesit
i panënshkruar int i;
vonesë e pavlefshme ()(
për (i=0;i<500000;i++);
}
int main(void)(
RCC->AHBENR|=(1<<21);
GPIOE->MODER|=0×10000;
ndersa (1)(
vonesë ();
GPIOE->ODR|=0×100;
vonesë ();
GPIOE->ODR&=~(0×100);
} }

2). SPL(Biblioteka standarde e pajisjeve periferike)- kjo bibliotekë është krijuar për të kombinuar të gjithë procesorët nga ST Electronics. Projektuar për ta bërë kodin më të lëvizshëm dhe synon kryesisht zhvilluesin fillestar. ST ka punuar në një zëvendësim SPL të quajtur "shtresë e ulët" që është në përputhje me HAL. Drejtuesit e shtresave të ulëta (LL) janë krijuar për të siguruar një shtresë pothuajse të lehtë të orientuar nga ekspertët që është më afër harduerit sesa HAL. Përveç HAL, API-të LL janë gjithashtu të disponueshme. Një shembull i të njëjtit program në SPL.

#përfshi
#përfshi
#përfshi
#define LED GPIO_Pin_8
int main() (
i gjatë i;
GPIO_InitTypeDef gpio;
// LED blu është i lidhur me portin E, pin 8 (autobus AHB)
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOE, ENABLE);
// Konfiguro portin E (LED)
GPIO_StructInit(&gpio); //deklarimi dhe inicializimi i variablit të strukturës së të dhënave
gpio.GPIO_Mode = GPIO_Mode_OUT;
gpio.GPIO_Pin = LED;
GPIO_Init(GPIOE, &gpio);
// LED që pulsojnë
ndersa (1) (
// Aktiv
GPIO_SetBits (GPIOE, LED);
për (i = 0; i< 500000; i++);
// Të gjitha jashtë
GPIO_ResetBits (GPIOE, LED);
për (i = 0; i< 500000; i++);
} }

Çdo funksion përshkruhet në dokumentacionin teknik Manuali i përdorimit UM1581 Përshkrimi i bibliotekës standarde periferike STM32F30xx/31xx. Këtu përfshijmë tre skedarë header që përmbajnë të dhënat e nevojshme, strukturat, funksionet e kontrollit të rivendosjes dhe sinkronizimit, si dhe për konfigurimin e porteve I/O.

3). HAL- (Niveli i aksesit të harduerit, shtresa e abstraksionit të harduerit)- Një tjetër bibliotekë e përbashkët e zhvillimit. Me të cilin doli programi CubeMX për konfigurimin që përdorëm në artikullin e fundit. Në të njëjtin vend, ne kemi shkruar një program për ndezjen e një LED duke përdorur këtë bibliotekë. Siç mund ta shihni në figurën më poshtë, kubi gjeneron drejtues HAL dhe CMSIS. Epo, le të përshkruajmë skedarët kryesorë të përdorur:
- system_stm32f3x.c dhe system_stm32f3x.h- të sigurojë grupe minimale funksionesh për konfigurimin e sistemit të klockimit;
- core_cm4.h - siguron akses në regjistrat e bërthamës dhe periferisë së saj;
- stm32f3x.h - skedari i kokës së mikrokontrolluesit;
- startup_system32f3x.s - kodi i fillimit, përmban një tabelë të vektorëve të ndërprerjeve, etj.

#include "main.h"
#include "stm32f3xx_hal.h"
void SystemClock_Config(void); /*Deklaroni funksionet e konfigurimit të orës*/
boshllëk statik MX_GPIO_Init(void); /*Inicializimi I/O*/
int main(void)(
/*Rivendosja e të gjitha pajisjeve periferike, Inicializon ndërfaqen Flash dhe Systick.*/
HAL_Init();
/* Konfiguro orën e sistemit */
SystemClock_Config();
/* Inicializoni të gjitha pajisjet periferike të konfiguruara */
MX_GPIO_Init();
ndersa (1) (
HAL_GPIO_TogglePin(GPIOE, GPIO_PIN_8); //Ndrysho gjendjen e këmbës
HAL_Vonesë (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;
nëse (HAL_RCC_OscConfig (&RCC_OscInitStruct) != HAL_OK){

}
/**Inicializon orët e autobusëve të CPU, AHB dhe APB */
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKBurimi = RCC_SYSCLKSOURCE_HSI;
RCC_ClkInitStruct.AHBCLKNdarës = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKNdarës = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKNdarës = RCC_HCLK_DIV1;
nëse (HAL_RCC_ClockConfig (&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK){
_Error_Handler (__FILE__, __LINE__);
}
/**Konfiguro kohën e ndërprerjes së Systick*/
HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
/**Konfiguro Systick */
HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
/* Konfigurimi i ndërprerjes SysTick_IRQn */
HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
}
/** Konfiguro kunjat si dalje analoge hyrëse EVENT_OUT EXTI */
boshllëk statik MX_GPIO_Init (i pavlefshëm){
GPIO_InitTypeDef GPIO_InitStruct;
/* Ora e porteve GPIO Aktivizo */
__HAL_RCC_GPIOE_CLK_ENABLE();
/*Konfiguro nivelin e daljes së pinit GPIO */
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);
/*Konfiguro kunjat GPIO: 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 (skedar char *, linjë int){
ndersa (1) (
} }
#ifdef USE_FULL_ASSERT

Assert_i pavlefshëm (skedar uint8_t*, rreshti uint32_t){
}
#përfundim
Këtu, si dhe në shembullin e mëparshëm, ne mund të shohim për shembull përshkrimin e secilit funksion në dokumentacion Manuali i përdorimit UM1786 Përshkrimi i STM32F3 HAL dhe drejtuesve të nivelit të ulët.

Mund të përmbledhim se opsioni i parë, duke përdorur CMSIS, është më pak i rëndë. Çdo bibliotekë ka dokumentacion. Në projektet e ardhshme, ne do të përdorim HAL dhe CMSIS, duke përdorur programin e konfigurimit STCube dhe, nëse është e mundur, do të përdorim regjistrat drejtpërdrejt, pa mbështjellës softuerësh. Këtu do të ndalemi sot. Në artikullin tjetër, ne do të shqyrtojmë parimet themelore të ndërtimit të një shtëpie të zgjuar. Të gjitha tani për tani.

Artikujt kryesorë të lidhur