Mikroprocesor STM32F407VG ARM Cortex-M4 · Keil µVision5 · SPŠE Havířov
Kapitola 1

Co je mikroprocesor a jeho obecný popis

Mikroprocesor lze definovat jako sekvenční automat vyrobený technologií VLSI (Very Large Scale Integration) — tedy integrovaný obvod s miliardami tranzistorů na jednom křemíkovém čipu. Tvoří ho tři základní součásti: řadič, ALU a pracovní registry. Samotný mikroprocesor není schopen provozu bez podpůrných obvodů — paměti, oscilátoru, vstupně-výstupních bloků. Teprve rozšířen o tyto součásti tvoří mikropočítač, a ten doplněný o periferie umožňující interakci s uživatelem se nazývá mikropočítačový systém.

1.1 Blokové schéma mikropočítačového systému

Následující diagram ukazuje hierarchii: mikroprocesor (řadič + ALU + registr instrukce) tvoří jádro mikropočítače. K němu se přidává paměť a I/O bloky. Celý systém je pak obklopen periferiemi — monitorem, klávesnicí, vnější pamětí.

Obr. 1 — Blokové schéma mikropočítačového systému (Čítač instrukcí, Řadič, ALU, sběrnice, paměť)
Obr. 1 — Blokové schéma mikropočítačového systému (Čítač instrukcí, Řadič, ALU, sběrnice, paměť)
1.2 Přirovnání — jak mikroprocesor pracuje

Výpočetní systém si lze představit jako člověka sedícího u stolu. Člověk je řadič — ovládá kalkulačku (ALU), jejíž ovládání je dáno programem (instrukcemi). Vstupní data zadává přes klávesnici (vstupní jednotka), výsledky vidí na displeji (výstupní jednotka). Na stole jsou položeny hodiny — každou minutu je proveden další příkaz. Příkazy na papíru jsou zpracovávány sekvenčně — od prvního k poslednímu, výjimkou jsou skokové instrukce. Ukazatel aktuálního příkazu je Program Counter (PC).

1.3 Instrukční cyklus — Fetch, Decode, Execute

Každá instrukce prochází třemi fázemi: Fetch — řadič čte binární kód instrukce z paměti na adrese, kam ukazuje registr PC. Decode — dekodér zjistí typ operace (ADD, MOV, BEQ...) a připraví operandy. Execute — ALU instrukci vykoná a výsledek uloží. Procesor bez pipeline dokončí každou instrukci celým cyklem, moderní procesory s pipeline zpracovávají více instrukcí najednou — každý takt dokončí jednu.

1.4 Von Neumannova architektura

Základem dnešních výpočetních strojů (od roku 1945) je Von Neumannova architektura. Klíčový princip: instrukce i data jsou členěny do slov/slabik stejného formátu, uloženy ve společné paměti a nijak speciálně nerozlišeny. Zpracování je sekvenční — instrukce za instrukcí. Struktura výpočetního stroje je nezávislá na řešeném problému — program uložený v paměti definuje, co stroj dělá. Paměť je rozdělena na buňky stejné velikosti, přistupuje se k nim pomocí adresy.

Obr. 2 — Von Neumannova architektura: tok dat (zelená), řídící signály řadiče (červená), stavová hlášení (oranžová)
Obr. 2 — Von Neumannova architektura: tok dat (zelená), řídící signály řadiče (červená), stavová hlášení (oranžová)

Nevýhodou je Von Neumannův bottleneck: CPU a paměť jsou propojeny jedinou sběrnicí — instrukce i data musí sdílet stejný kanál, procesor nemůže současně číst instrukci a přistupovat k datům. Instrukce a data jsou binárně zakódována a vzájemně nerozeznatelná (záměna instrukcí a dat je technicky možná — self-modifying code).

1.5 Harvardská architektura

Harvardská architektura odděluje paměť pro data a program — fyzicky jsou to dvě samostatné paměti se dvěma oddělenými sběrnicemi. Díky tomu lze instrukci a data načítat souběžně, bez vzájemného blokování. Paměti nemusí mít stejné parametry (Flash pro program, SRAM pro data). Nevýhodou je, že nevyužitou část jedné paměti nelze přidělit druhé. Nenastane situace vlastního přepsání (program nemůže přepsat sám sebe přes datovou sběrnici). Řízení CPU je odděleno od řízení V/V jednotek — nejsou napojeny přímo na ALU. Příklady: Atmel 8051, ARM (v modifikované podobě).

Obr. 3 — Harvardská architektura: oddělená Data Memory a Instruction Memory, samostatné sběrnice, CLOCK, STATUS
Obr. 3 — Harvardská architektura: oddělená Data Memory a Instruction Memory, samostatné sběrnice, CLOCK, STATUS
Obr. 4 — Srovnání Von Neumann (vlevo: Memory Data+Code, jedna sběrnice) vs. Harvardská architektura (vpravo: Program Memory + Data Memory, oddělené sběrnice)
Obr. 4 — Srovnání Von Neumann (vlevo: Memory Data+Code, jedna sběrnice) vs. Harvardská architektura (vpravo: Program Memory + Data Memory, oddělené sběrnice)
1.6 Modifikovaná Harvardská architektura

ARM Cortex-M4 používá modifikovanou Harvardskou architekturu: uvnitř jádra jsou fyzicky odděleny instrukční sběrnice (I-BUS) a datová sběrnice (D-BUS), takže fetch a datový přístup probíhají paralelně. Z pohledu programátora je však adresový prostor unifikovaný — Flash, RAM i periferie leží v jednom lineárním adresovém prostoru 0x00000000–0xFFFFFFFF. Výsledek: výkon Harvardské architektury + flexibilita Von Neumannovy architektury.

VlastnostVon NeumannHarvardskáMod. Harvardská (ARM)
Paměť programu a datSdílenáOddělenáLogicky unifikovaná, fyzicky oddělená
SběrniceJedna sdílenáDvě oddělenéDvě uvnitř jádra, jedna navenek
Paralelní fetch+dataNeAnoAno (uvnitř jádra)
Flexibilita pamětiVysokáNízkáStřední
Typické použitíPC, serveryDSP, AVR, PICARM Cortex-M, STM32
1.7 RISC vs. CISC

CISC (Complex Instruction Set Computer) — instrukce jsou komplexní, každá může provést více operací. Proměnná délka instrukcí (1–15 B u x86). Program je kratší, ale dekódování složité. Příklady: Intel x86/x64.

RISC (Reduced Instruction Set Computer) — instrukce jsou jednoduché, pevná délka (2 nebo 4 B), typicky 1 cyklus. Přirozená pipeline. Program je delší, ale každá instrukce je rychlá. Příklady: ARM, MIPS, RISC-V, AVR.

ARM Cortex-M4 používá Thumb-2 — hybridní instrukční sada kombinující 16bitové Thumb instrukce (kompaktní kód) a 32bitové ARM instrukce (výkon). Historicky: první ARM procesor vyrobila firma Acorn Computers, ARM = Acorn Risc Machine, dnes Advanced RISC Machine. ARM Holdings (britská společnost, zal. 1990 firmami Acorn, Apple a VLSI Technology) architekturu vyvíjí a licencuje — samotné čipy vyrábí až výrobci jako ST, Apple, Qualcomm, Samsung, Nvidia. Ročně se vyrobí přes 50 miliard ARM čipů.

VlastnostCISCRISC
Délka instrukcíProměnná (1–15 B)Pevná (2 nebo 4 B)
Počet instrukcí v programuMéněVíce
Doba trvání instrukce1 až mnoho cyklůTypicky 1 cyklus
PipelineSložitáPřirozená
PříkladyIntel x86, AMD64ARM, MIPS, RISC-V, AVR
1.8 Typy procesorů

Procesory se dělí nejen na RISC/CISC, ale i podle šířky operandu a použití:

  • MCU (Microcontroller Unit) — nejjednodušší skupina, mikrořadiče. Malé rozměry, nízká cena a spotřeba, slabší výkon. Vyráběny pro přesně určenou specifickou činnost s minimální možností rozšíření. Příklad: STM32, AVR.
  • CPU (Central Processing Unit) — základní řídicí jednotka PC. Mnohem vyšší výkon, větší rozměry, větší spotřeba. Jednodušší a širší možnost rozšíření — otevřená architektura, velké množství pinů/signálů. Příklad: Intel Core, AMD Ryzen.
  • DSP (Digital Signal Processing) — kompromis mezi MCU a CPU. Návrh optimalizovaný pro algoritmy zpracování digitálních signálů. Vysoký výkon v oblasti zpracování velkého objemu dat v reálném čase. Využití v měřicí technice, zvukových kartách, mobilech.
  • GPU (Graphics Processing Unit) — speciální procesory pro grafické karty. Řídí zpracování obrazových dat a výpočty fyzikálního modelu 3D scény.
  • APU (Accelerated Processing Unit) — v jednom pouzdře CPU i GPU, moderní procesory.
  • NPU (Network Processing Unit) — součást přepínačů, směrovačů a síťových zařízení.

Procesory se dělí také podle šířky slova: 4, 8, 16, 32, 64 bit. Šířka určuje, jak velká čísla procesor zpracuje v jednom kroku a jak velké jsou jeho registry.

1.9 Sběrnice

Sběrnice (bus) je sdílené komunikační médium. Každá sběrnice se skládá ze tří skupin vodičů: adresová sběrnice (CPU vysílá adresu — 32bit = 4 GB adresovatelného prostoru), datová sběrnice (přenáší data — 8/16/32/64 bit šířka) a řídicí sběrnice (R/W, CS, CLK, IRQ). V STM32F407 jsou sběrnice hierarchicky organizovány: AHB (168 MHz, jádro + paměti + DMA), APB2 (84 MHz, ADC, TIM1/8, USART1/6) a APB1 (42 MHz, TIM2–7, USART2–5, SPI2/3, I2C).

Obr. 5 — AMBA sběrnicová architektura: AHB (ARM Processor, On-Chip RAM, DMA) → Bridge → APB (UART, Timer, Keypad, PIO)
Obr. 5 — AMBA sběrnicová architektura: AHB (ARM Processor, On-Chip RAM, DMA) → Bridge → APB (UART, Timer, Keypad, PIO)
1.10 Řadič (Control Unit)

Řadič je ta část mikroprocesoru, která čte instrukce a koordinuje ostatní části. Obsahuje: registr instrukce (uchovává právě načtenou instrukci), registr adresy (adresa příští instrukce = Program Counter), dekodér instrukce (rozpozná typ operace) a generátor řídících impulzů (vydává řídicí signály pro ALU a paměť). Řadič sám nic nepočítá — pouze orchestruje.

1.11 ALU — Aritmeticko-logická jednotka

ALU je kombinační obvod — bezpaměťová "kalkulačka" procesoru. Provádí: sčítání, odčítání, logický AND/OR/XOR/NOT, bitový posun (shift), porovnání. Nastavuje stavové příznaky (flags): N (Negative), Z (Zero), C (Carry), V (Overflow). Tyto příznaky využívají podmíněné instrukce (BEQ, BNE, BGT...) pro větvení programu — základ if/else a smyček v C. Cortex-M4 navíc obsahuje FPU (Floating Point Unit) pro hardwarové operace s float čísly dle IEEE 754.

Obr. 6 — Detailní schéma činnosti mikroprocesoru: Řadič (registr instrukce, dekodér, generátor impulzů) + Aritmetická jednotka (registr příznaků, střadač, operační blok)
Obr. 6 — Detailní schéma činnosti mikroprocesoru: Řadič (registr instrukce, dekodér, generátor impulzů) + Aritmetická jednotka (registr příznaků, střadač, operační blok)
Kapitola 2

Rozdíl mezi mikroprocesorem a mikrokontrolérem

Mikroprocesor (MPU) je pouze výpočetní motor — CPU jádro (řadič + ALU + registry). Bez podpůrných obvodů není schopen provozu. Potřebuje externí: RAM, Flash/ROM, hodinový oscilátor, řadiče sběrnic, I/O expandéry. Příklad: Intel Core i7, 8086.

Mikrokontrolér (MCU) má vše integrováno na jednom čipu: CPU jádro + Flash paměť pro program + SRAM pro data + periferie (GPIO, timery, ADC, DAC, UART, SPI, I2C, USB...). Stačí přidat napájení, oscilátor a program — systém funguje.

VlastnostMikroprocesor (MPU)Mikrokontrolér (MCU)
Paměť RAMExterní (DIMM moduly)Interní (SRAM na čipu)
Paměť programuHDD/SSD přes OSInterní Flash
Periferie (GPIO, UART...)Ext. čipy / SoCIntegrované na čipu
Spotřeba energieVyšší (Watty)Nižší (mW až µW)
Výpočetní výkonVelmi vysoký (GHz, multicore)Střední (MHz, single-core)
PříkladIntel Core, ARM Cortex-ASTM32, AVR, PIC, ESP32

Náš STM32F407VG je mikrokontrolér — na jediném čipu nese 32bitové ARM Cortex-M4 jádro, 1 MB Flash, 192 KB RAM a desítky periferií. ARM jako součást SoC (System on Chip) integruje: grafické jádro, operační paměť, síťový čip, I/O rozhraní, modem... Výhody SoC: levnější výroba, nižší spotřeba, vysoká integrace. Nevýhoda: malá možnost HW konfigurace.

Kapitola 3

Charakteristika procesoru ARM STM32F4

3.1 Architektura — ARM Cortex-M4

Cortex-M4 patří do rodiny ARMv7E-M — 32bitová RISC architektura. Označení jader jsou Cortex, označení architektur ARMvX: Cortex-M4 → ARMv7, Cortex-A55 → ARMv8.2. Klíčové vlastnosti jádra:

  • 32bitová datová šířka — operace s 32bitovými čísly jsou nativní.
  • Modifikovaná Harvardská architektura — I-BUS, D-BUS a S-BUS uvnitř jádra.
  • 5-stupňový pipeline (Fetch → Decode → Register Read → Execute → Write-back).
  • Thumb-2 instrukční sada — 16bitové i 32bitové instrukce.
  • Hardwarová násobička (1 cyklus) a dělička (2–12 cyklů).
  • DSP rozšíření — SIMD, MAC (Multiply-Accumulate) instrukce.
  • FPU (Floating Point Unit) — single-precision float dle IEEE 754.
  • MPU (Memory Protection Unit) — volitelná ochrana paměťových regionů.
  • NVIC (Nested Vectored Interrupt Controller) — integrovaný řadič přerušení.
Obr. 7 — 5-stupňový pipeline ARM9 TDMI: fetch (I-cache) → instruction decode → register read → execute (ALU, shift) → buffer/data (D-cache) → write-back
Obr. 7 — 5-stupňový pipeline ARM9 TDMI: fetch (I-cache) → instruction decode → register read → execute (ALU, shift) → buffer/data (D-cache) → write-back
3.2 Paměti STM32F407VG

STM32F407 mapuje vše do jednoho 32bitového adresního prostoru (0x00000000–0xFFFFFFFF). Na Discovery kitu je k dispozici: 1 MB Flash, 112 KB SRAM1, 16 KB SRAM2, 64 KB CCM RAM, 4 KB Backup SRAM. Celkem 192+4 KB RAM. Podporované externí paměti: Compact Flash, NAND, NOR Flash, SRAM, PSRAM.

Typ pamětiVelikostAdresaÚčel
Flash1 024 KB0x0800_0000Program, const data, vektory přerušení
SRAM1112 KB0x2000_0000Globální proměnné, zásobník, halda
SRAM216 KB0x2001_C000Datová RAM
CCM RAM64 KB0x1000_0000Core Coupled — 0 wait states, bez DMA
Backup SRAM4 KB0x4002_4000Záloha dat při výpadku napájení

STM32F407VGTx (pouzdro LQFP100) má 140 I/O pinů, porty A–K (pro uživatele A–E), 14 časovačů (16/32bit), 3× 12bit ADC, 2× 12bit DAC, 4× USART, 3× I2C, 3× SPI, USB 2.0, Ethernet 10/100 Mb/s, generátor náhodných čísel. CLK až 168 MHz, interní 16 MHz RC nebo 32 kHz. Debug: ST-LINK/V2 (SWD).

3.3 Blokové schéma STM32F407
Obr. 8 — Blokové schéma STM32F407: ARM Cortex-M4 (168 MHz, FPU), AHB bus-matrix 8S7M, Flash 1 MB, SRAM 112+16 KB, CCM 64 KB, GPIO porty A–I, DMA1/2, USB OTG, Ethernet MAC, NVIC, MPU, JTAG/SW
Obr. 8 — Blokové schéma STM32F407: ARM Cortex-M4 (168 MHz, FPU), AHB bus-matrix 8S7M, Flash 1 MB, SRAM 112+16 KB, CCM 64 KB, GPIO porty A–I, DMA1/2, USB OTG, Ethernet MAC, NVIC, MPU, JTAG/SW
Obr. 9 — Blokové schéma STM32F407 — periferie: APB2 (TIM1/8/9/10/11, USART1/6, SPI1, ADC) a APB1 (TIM2–7/12–14, USART2–5, SPI2/3, I2C1–3, DAC, CAN)
Obr. 9 — Blokové schéma STM32F407 — periferie: APB2 (TIM1/8/9/10/11, USART1/6, SPI1, ADC) a APB1 (TIM2–7/12–14, USART2–5, SPI2/3, I2C1–3, DAC, CAN)
3.4 Registry procesoru

Cortex-M4 má 16 hlavních registrů + speciální: R0–R12 (obecné, R0–R3 = parametry funkcí a návratová hodnota), R13/SP (Stack Pointer — zásobník roste dolů, MSP pro privilegovaný kód, PSP pro RTOS vlákno), R14/LR (Link Register — návratová adresa při volání funkcí), R15/PC (Program Counter — adresa příští instrukce), APSR (Application PSR — příznaky N,Z,C,V), CONTROL (privilegovaný/neprivilegovaný režim), PRIMASK/FAULTMASK/BASEPRI (maskování přerušení — základ __disable_irq() / __enable_irq()).

3.5 Hodinový systém — RCC

Celý MCU potřebuje hodinový signál. Modul RCC (Reset and Clock Control) řídí všechny hodinové signály. Na Discovery kitu: interní HSI oscilátor 16 MHz. Pomocí PLL lze dosáhnout až 168 MHz. Sběrnice mají předděličky: AHB (max 168 MHz), APB2 (max 84 MHz), APB1 (max 42 MHz). Klíčové: každá periferie musí mít povolen hodinový signál zápisem do RCC registrů — bez toho jsou registry periferie nedostupné.

Kapitola 4

Popis Portů — GPIO

GPIO (General Purpose Input/Output) — 140 I/O pinů organizovaných do portů A–I, každý port má až 16 pinů. Každý port má vlastní sadu registrů. Před použitím je nutné vždy povolit hodinový signál pro daný port zápisem do RCC→AHB1ENR.

4.1 Registr RCC→AHB1ENR
Obr. 10 — RCC AHB1 peripheral clock enable register (RCC_AHB1ENR): bity GPIOAEN, GPIOBEN, GPIOCEN, GPIODEN, GPIOEEN... pro aktivaci hodinového signálu příslušného portu
Obr. 10 — RCC AHB1 peripheral clock enable register (RCC_AHB1ENR): bity GPIOAEN, GPIOBEN, GPIOCEN, GPIODEN, GPIOEEN... pro aktivaci hodinového signálu příslušného portu
4.2 GPIOx→MODER — nastavení směru pinu

Každý pin je konfigurován 2 bity v registru MODER: 00 = vstup (reset state), 01 = výstup (GPIO output), 10 = alternativní funkce (AF), 11 = analogový mód.

Obr. 11 — GPIOx_MODER: 2 bity na pin (MODER15[1:0] až MODER0[1:0]). Bits 2y:2y+1 konfigurují pin y.
Obr. 11 — GPIOx_MODER: 2 bity na pin (MODER15[1:0] až MODER0[1:0]). Bits 2y:2y+1 konfigurují pin y.
4.3 GPIOx→IDR a GPIOx→ODR
Obr. 12 — GPIOx_IDR (Input Data Register): bity IDR15–IDR0, read-only, obsahují aktuální hodnotu na vstupních pinech
Obr. 12 — GPIOx_IDR (Input Data Register): bity IDR15–IDR0, read-only, obsahují aktuální hodnotu na vstupních pinech
Obr. 13 — GPIOx_ODR (Output Data Register): bity ODR15–ODR0, read/write. Pro atomický set/reset použít GPIOx_BSRR.
Obr. 13 — GPIOx_ODR (Output Data Register): bity ODR15–ODR0, read/write. Pro atomický set/reset použít GPIOx_BSRR.

Registr BSRR (Bit Set/Reset Register) umožňuje atomicky nastavit nebo resetovat piny jedním zápisem: dolních 16 bitů = set, horních 16 bitů = reset. Toto zabraňuje nekonzistentním stavům při přerušení uprostřed read-modify-write operace na ODR.

4.4 Alternativní funkce (AF)

Piny mohou být přepojeny na interní periferie (UART, SPI, I2C, timery...) pomocí registru AFR[0/1] (4 bity na pin, hodnoty AF0–AF15). Například PA2 = TX USART2 = AF7, PA3 = RX USART2 = AF7. Nejprve je nutné nastavit MODER na 10 (alternativní funkce), poté zapsat číslo AF do AFR.

C — příklady inicializace GPIO
// Příklad: inicializace PA2 jako TX USART2 (AF7)
pin_enable(PA2);               // RCC->AHB1ENR |= GPIOAEN
pin_mode(PA2, PIN_MODE_AF);    // MODER |= (0b10 << 2*2)
pin_af(PA2, PIN_AF7);          // AFR[0] |= (7 << 4*2)

// Příklad: interní LED PD12 jako výstup
pin_enable(LED_IN_0);          // Hodinový signál pro port D
pin_mode(LED_IN_0, PIN_MODE_OUTPUT); // MODER: pin 12 = 01 (výstup)
io_set(LED_IN_0, 1);           // BSRR: nastavit PD12 = 1 -> LED svítí
Kapitola 5

Čítače a časovače — realizace časových smyček

5.1 Úvod — SysTick

Nejjednodušší časovač je SysTick — jednoduchý interní systémový časovač, součást jádra Cortex. Při podtečení (od nastavené hodnoty dolů na 0) vyvolá přerušení. Periodicky odčítá jedničku od uživatelem definované hodnoty. Využití: pravidelná kontrola sériového kanálu, klávesnice, tlačítek; časování pro LCD driver; blikání LED. Funkce delay_ms() a delay_us() v knihovně jsou implementovány právě přes SysTick.

Obr. 14 — System Tick Timer SysTick: jednoduchý interní systémový časovač součástí jádra Cortex, při podtečení volá přerušení
Obr. 14 — System Tick Timer SysTick: jednoduchý interní systémový časovač součástí jádra Cortex, při podtečení volá přerušení
5.2 TIM6 a TIM7 — základní časovače

TIM6 a TIM7 jsou 16bitové základní časovače (respektive vzestupné čítače s možností auto-reload). Součástí je 16bitový programovatelný prescaler — využívaný jako dělička frekvence. Při přetečení nebo dosažení hodnoty auto-reload může být generováno přerušení nebo signál pro DMA. Lze je využít i pro řízení DAC.

Obr. 15 — TIM6 a TIM7: základní časovače, 16bit vzestupný čítač s auto-reload, prescaler, možnost DMA a přerušení při přetečení
Obr. 15 — TIM6 a TIM7: základní časovače, 16bit vzestupný čítač s auto-reload, prescaler, možnost DMA a přerušení při přetečení
5.3 Klíčové registry časovače
Obr. 16 — Klíčové registry TIM6/TIM7: PSC (Prescaler), ARR (Auto-Reload Register), CNT (Counter), CR1 (CEN = spuštění), SR (UIF = příznak přetečení), DIER (UIE = povolení přerušení)
Obr. 16 — Klíčové registry TIM6/TIM7: PSC (Prescaler), ARR (Auto-Reload Register), CNT (Counter), CR1 (CEN = spuštění), SR (UIF = příznak přetečení), DIER (UIE = povolení přerušení)
5.4 Výpočet periody — PSC a ARR
Vzorec pro periodu přetečení časovače

T = (PSC + 1) × (ARR + 1) / f_clk

PSC — hodnota Prescaleru zapsaná do TIM->PSC
ARR — hodnota Auto-Reload Register v TIM->ARR
f_clk — frekvence hodinového signálu přiváděného na časovač [Hz]

Příklad: f_clk = 16 MHz, cíl T = 200 ms:
PSC = 159 → f_tim = 16 000 000 / (159+1) = 100 000 Hz
ARR = 19 999 → T = 160 × 20 000 / 16 000 000 = 0,200 s = 200 ms
Obr. 17 — Příklady nastavení TIM6: pro různé kombinace PSC a ARR a různé vstupní frekvence (16 MHz, 100 kHz, 10 kHz) s dobami přetečení od 4,1 ms po 6,5 s
Obr. 17 — Příklady nastavení TIM6: pro různé kombinace PSC a ARR a různé vstupní frekvence (16 MHz, 100 kHz, 10 kHz) s dobami přetečení od 4,1 ms po 6,5 s
5.5 Polling vs. přerušení
C — polling
// POLLING --- procesor aktivně čeká na přetečení:
TIM6->CR1 |= TIM_CR1_CEN;          // Start časovače
while (1) {
    if (TIM6->SR & TIM_SR_UIF) {   // Přeteklo? (UIF = Update Interrupt Flag)
        TIM6->SR &= ~TIM_SR_UIF;   // Smazat příznak --- POVINNÉ!
        TIM6->CNT = TIMx_CNT;      // Reset počítadla
        io_set(LED_IN_0, !io_get(LED_IN_0)); // Akce
    }
}
Kapitola 6

Přerušovací systém

6.1 Princip přerušení

Přerušení (interrupt) je mechanismus, kterým periferie nebo výjimečná situace upozorní procesor, že nastal důležitý event. Analogie: místo neustálého chodění ke dveřím a kontroly (polling), nainstalujete zvonek (interrupt). Periférie vysílá žádost IRQ (Interrupt Request) → řadič přerušení ji přijme (může jich přijít více najednou) → pošle signál INT procesoru → procesor odpoví INTA (interrupt acknowledge) → řadič sdělí typ přerušení → procesor podle tabulky vektorů přerušení skočí na příslušný podprogram (ISR).

Obr. 18 — Přerušení: periferie → IRQ → řadič přerušení → INT → procesor → vektor → ISR (podprogram přerušení v paměti)
Obr. 18 — Přerušení: periferie → IRQ → řadič přerušení → INT → procesor → vektor → ISR (podprogram přerušení v paměti)
Obr. 19 — Činnost řadiče přerušení: 1) IRQ — žádost, 2) příjem žádosti (může přijít více najednou), 3) INT — přerušení CPU, 4) uložení kontextu, 5) typ přerušení, 6) nový ukazatel CS/IP, 7) adresa ISR z vektoru
Obr. 19 — Činnost řadiče přerušení: 1) IRQ — žádost, 2) příjem žádosti (může přijít více najednou), 3) INT — přerušení CPU, 4) uložení kontextu, 5) typ přerušení, 6) nový ukazatel CS/IP, 7) adresa ISR z vektoru
6.2 NVIC — Nested Vectored Interrupt Controller

Cortex-M4 má integrovaný NVIC (Nested Vectored Interrupt Controller). Klíčové vlastnosti: vektorová tabulka v paměti Flash na adrese 0x08000000 (ukazatele na ISR), vnořená přerušení (vyšší priorita přeruší obsluhu nižší), až 240 externích přerušení + 16 systémových výjimek (NMI, HardFault, SysTick...), programovatelné priority (0–15, nižší číslo = vyšší priorita), tail-chaining (přechod mezi ISR trvá jen 6 cyklů), late-arrival (vyšší priorita vyhraje nad rozestavěnou nižší).

Při příchodu přerušení HW automaticky za 12 cyklů: uloží R0–R3, R12, LR, PC, xPSR na zásobník → načte adresu ISR z vektoru → skočí na ISR → po návratu (BX LR) obnoví registry a pokračuje. Programátor musí v ISR smazat příznak přerušení, jinak se ISR volá znovu donekonečna. Např. pro TIM6: TIM6->SR &= ~TIM_SR_UIF;

Obr. 20 — NVIC registry a vektory přerušení — tabulka se základní adresou, priority, enable bity
Obr. 20 — NVIC registry a vektory přerušení — tabulka se základní adresou, priority, enable bity
6.3 EXTI — External Interrupt

Pro přerušení od GPIO pinů slouží EXTI (External Interrupt/Event Controller). 16 linek (EXTI0–EXTI15), každá obsluhuje pin _n ze všech portů. Na jednu linku lze připojit jen jeden port najednou (volba přes SYSCFG_EXTICR). Přerušení lze spouštět na náběžnou hranu (0→1), sestupnou hranu (1→0) nebo obě. Tlačítko USER_BUTTON (PA0) → EXTI0, náběžná hrana.

6.4 Kritické sekce

Při inicializaci periferií se používá vzor __disable_irq() ... __enable_irq(). Toto dočasně zakáže všechna maskovaná přerušení zápisem do registru PRIMASK. Důvod: inicializace GPIO trvá více kroků a přerušení uprostřed by mohlo vidět polovičně inicializovanou periferii — zakázáním IRQ zajistíme atomičnost víceregistrové operace.

Kapitola 7

Charakteristika školního kitu — STM32F4-Discovery

Školní kit je deska STM32F4-Discovery (STM32F407VGTx) od STMicroelectronics. Obsahuje MCU, programátor ST-Link/V2, krystal 8 MHz. Školní přípravek rozšiřuje základní desku o: LCD 8×2, klávesnici 4×3, 4× externí LED (aktivní LOW na portu E), COM port, fotorezistor 10 kΩ, reproduktor.

7.1 Interní LED a tlačítko

Na desce jsou 4 uživatelské LED na portu D (PD12–PD15) a 2 tlačítka (modré PA0 = USER_BUTTON, černé = RESET). Interní LED jsou aktivní HIGH — svítí při log. 1.

LEDPinBarvaSvítí při
LD4PD12 (LED_IN_0)Zelenálog. 1 (High)
LD3PD13 (LED_IN_1)Oranžoválog. 1 (High)
LD5PD14 (LED_IN_2)Červenálog. 1 (High)
LD6PD15 (LED_IN_3)Modrálog. 1 (High)
7.2 Externí LED

Vnější LED na portu E (PE12–PE15) jsou aktivní LOW — svítí při log. 0. Proto je LED_setup() zhasíná zápisem io_set(LED_EX_x, 1).

PinMakroSvítí při
PE12LED_EX_0log. 0 (Low) — aktivní LOW
PE13LED_EX_1log. 0 (Low)
PE14LED_EX_2log. 0 (Low)
PE15LED_EX_3log. 0 (Low)
C — LED ovládání
LED_setup();               // Inicializace: int. výstup HIGH, ext. výstup HIGH (zhasnuté)
io_set(LED_IN_0, 1);       // PD12 = 1 → zelená LED svítí
io_set(LED_EX_0, 0);       // PE12 = 0 → červená ext. LED svítí
TOGGLE_BIT(GPIOD->ODR, 12); // XOR bit 12 → přepnutí stavu LED
7.3 LCD displej — HD44780

Alfanumerický LCD 8×2 (8 sloupců, 2 řádky) s řadičem HD44780. Komunikuje přes 4bitové paralelní rozhraní: datové vodiče DB4–DB7 + řídicí RS, R/W, EN.

Obr. 21 — LCD HD44780: alfanumerický displej, komunikace 4bit nebo 8bit, řadič HD44780 standard
Obr. 21 — LCD HD44780: alfanumerický displej, komunikace 4bit nebo 8bit, řadič HD44780 standard
Obr. 22 — Zapojení LCD na školním kitu: RS=PE3, RW=PE4, EN=PE5, DB4=PE6, DB5=PE7, DB6=PE8, DB7=PE9
Obr. 22 — Zapojení LCD na školním kitu: RS=PE3, RW=PE4, EN=PE5, DB4=PE6, DB5=PE7, DB6=PE8, DB7=PE9

8bitový příkaz nebo ASCII kód znaku se posílá ve dvou nibblech (4 bity najednou): nejprve horní 4 bity, poté dolní 4 bity. Každý nibble je odeslán pulzem na EN vodiči. RS=0 → příkaz, RS=1 → data (znak).

Obr. 23 — LCD 4bitová komunikace: 8bit příkaz/data se posílá ve dvou nibblech přes DB4–DB7, EN pulse latchuje data do LCD
Obr. 23 — LCD 4bitová komunikace: 8bit příkaz/data se posílá ve dvou nibblech přes DB4–DB7, EN pulse latchuje data do LCD
Obr. 24 — Inicializační sekvence LCD: reset (3× cmd 0x3), přepnutí do 4bit režimu (0x2), Function Set (0x28: 4bit/2řádky/5×8), Display ON (0x0F), Entry Mode (0x06), Clear (0x01)
Obr. 24 — Inicializační sekvence LCD: reset (3× cmd 0x3), přepnutí do 4bit režimu (0x2), Function Set (0x28: 4bit/2řádky/5×8), Display ON (0x0F), Entry Mode (0x06), Clear (0x01)
C — LCD API
LCD_setup();           // Inicializace LCD
LCD_set(LCD_CLR);      // Smazat displej (0x01)
LCD_set(LCD_LINE1);    // Přejít na řádek 1 (0x80)
LCD_print("Hello!");   // Vypsat řetězec
LCD_set(LCD_LINE2);    // Přejít na řádek 2 (0xC0)
LCD_goto(3, 2);        // Pozice sloupec 3, řádek 2
LCD_symbol('X');       // Vypsat jeden znak
7.4 Klávesnice (KeyPad)
Obr. 25 — Klávesnice KeyPad: maticové zapojení, řádky a sloupce, školní kit má 4×3 (12 kláves)
Obr. 25 — Klávesnice KeyPad: maticové zapojení, řádky a sloupce, školní kit má 4×3 (12 kláves)

Školní klávesnice je maticová 3×4. Fyzicky jsou spínače zapojeny v matici — každý na průsečíku řádku a sloupce. Stačí tak 3+4 = 7 pinů místo 12.

Obr. 26 — Maticové zapojení klávesnice 4×4: průsečík řádku a sloupce = klávesa. Sloupce = vstup s pull-up, řádky = výstup
Obr. 26 — Maticové zapojení klávesnice 4×4: průsečík řádku a sloupce = klávesa. Sloupce = vstup s pull-up, řádky = výstup

Zapojení na kitu: COL0–COL2 → PD0–PD2 (vstup + pull-up), ROW0–ROW3 → PD6–PD9 (výstup push-pull). Princip čtení — row scanning:

  • 1. Aktivujeme řádek n (ROW_n = 0, ostatní = 1).
  • 2. Přečteme stav sloupců (IDR).
  • 3. Pokud COL_m = 0, je stisknuta klávesa na průsečíku ROW_n × COL_m.
  • 4. Vrátíme KBD_MAP[n][m] — ASCII kód klávesy.
Obr. 27 — Princip row-scanning: aktivace každého řádku a čtení sloupců. Debouncing: delay_ms(KEYPAD_STEP=150) na začátku KBD_read()
Obr. 27 — Princip row-scanning: aktivace každého řádku a čtení sloupců. Debouncing: delay_ms(KEYPAD_STEP=150) na začátku KBD_read()
C — klávesnice API
static uint8_t KBD_MAP[KEYPAD_ROWS][KEYPAD_COLS] = {
    {'1','2','3'}, {'4','5','6'}, {'7','8','9'}, {'*','0','#'}
};
KBD_setup();               // Sloupce=vstup+pull-up, řádky=výstup
uint8_t key = KBD_read();  // Vrátí ASCII nebo 0 (nic nestisknuto)
if (key) LCD_symbol(key);  // Zobrazit na LCD
7.5 UART — sériová komunikace

UART (Universal Asynchronous Receiver-Transmitter) — sériový protokol bez hodinového signálu. Dva vodiče: TX (vysílání) a RX (příjem). Frame: 1 start bit + 8 datových bitů + 1 stop bit. Školní kit: USART2 na PA2(TX)/PA3(RX), AF7, 9600 Bd. Výpočet BRR: USARTDIV = f_PCLK / (16 × BaudRate) = 16 000 000 / (16 × 9600) = 104,167 → mantissa=104, fraction=3 → BRR=0x0683.

C — UART API
UART_setup();              // Init USART2 @ 9600 Bd, PA2/PA3 AF7
UART_putc('A');            // Odeslat jeden znak (blokující)
UART_write("Hello
", 7); // Odeslat řetězec
uint8_t c = UART_getc();   // Přijmout znak (blokující)
char buf[32];
UART_read(buf, sizeof(buf)); // Přijmout řetězec do 
 nebo 
Kapitola 8

Konfigurace projektu a práce v IDE Keil µVision5

Keil µVision5 je profesionální IDE pro vývoj embedded systémů na ARM procesorech. Obsahuje editor, kompilátor (ARM Compiler 5/6), linker, debugger a simulátor. Výběr čipu: STMicroelectronics → STM32F4 Series → STM32F407 → STM32F407VGTx. Preprocessor definice: STM32_TYPE=407.

SouborUmístěníFunkce
startup_stm32f407xx.sRTE/Device/Startupový kód: zásobník, vektorová tabulka, volání main()
system_stm32f4xx.cRTE/Device/Inicializace SystemCoreClock, SystemInit()
stm32_kit.hstm32/include/Centrální include: vybere desku, includuje CMSIS
config.hstm32/config/LCD_COLS, LCD_ROWS, KEYPAD_COLS, KEYPAD_ROWS
f407.hstm32/boards/disc/Definice pinů: LED_IN_0=PD12, LCD_RS=PE3, UART_TX=PA2...
app.c / main.csrc/Vlastní kód — funkce setup() a main()

Klíčové kroky projektu: Build (F7) → Download/Flash (F8) → Debug (F5). V debuggeru: breakpointy (F9), krokování (F10/F11), Watch okno pro proměnné, Peripherals → System Viewer pro zobrazení všech registrů MCU v reálném čase (MODER, IDR, ODR, TIM6→SR...).

C — kompletní šablona projektu
#include "stm32_kit.h"
#include "stm32_kit/led.h"
#include "stm32_kit/lcd.h"
#include "stm32_kit/keypad.h"
#include "stm32_kit/uart.h"
#include "stm32_kit/timers.h"

#define TIMx_PSC 159
#define TIMx_ARR 19999
#define TIMx_CNT 0

static uint8_t KBD_MAP[KEYPAD_ROWS][KEYPAD_COLS] = {
    {'1','2','3'}, {'4','5','6'}, {'7','8','9'}, {'*','0','#'}
};

BOARD_SETUP void setup(void) {  // Voláno automaticky před main()
    LED_setup();
    LCD_setup();
    KBD_setup();
    UART_setup();
    TIM6_setup();
}

int main(void) {
    TIM6_config();
    TIM6->CR1 |= TIM_CR1_CEN;
    LCD_set(LCD_CLR);
    LCD_print("STM32F407 Ready");
    while (1) {
        if (TIM6->SR & TIM_SR_UIF) {
            TIM6->SR &= ~TIM_SR_UIF;
            io_set(LED_IN_0, !io_get(LED_IN_0));
        }
        uint8_t key = KBD_read();
        if (key) { LCD_set(LCD_LINE2); LCD_symbol(key); UART_putc(key); }
    }
}
Shrnutí

Klíčové pojmy a hodnoty

PojemHodnota / Definice pro STM32F407
TypMikrokontrolér (MCU) — CPU + Flash + RAM + periferie na jednom čipu
ArchitekturaARM Cortex-M4, ARMv7E-M, 32bit RISC, Thumb-2, modif. Harvardská
Max. frekvence168 MHz s PLL; Discovery kit: 16 MHz HSI (bez PLL)
Flash1 024 KB @ 0x08000000
SRAM celkem192 KB (112+16+64 CCM)
Pipeline5-stupňový (Fetch→Decode→RegRead→Execute→WriteBack)
GPIOPorty A–I, 16 pinů, MODER: 00=vstup 01=výstup 10=AF 11=analog
Interní LEDPD12–PD15, aktivní HIGH, 4 barvy
Externí LEDPE12–PE15, aktivní LOW
LCDHD44780, 4bit, RS=PE3, RW=PE4, EN=PE5, DB4–7=PE6–9
Klávesnice3×4 matice, COL=PD0–2 (pull-up vstup), ROW=PD6–9 (výstup)
UARTUSART2, PA2(TX)/PA3(RX), AF7, 9600 Bd
Časovač TIM616bit, PSC+ARR, přetečení = UIF flag v SR
SysTick24bit sestupný čítač v jádře Cortex, podtečení → přerušení
NVICVektorový řadič přerušení, priority 0–15, nested, tail-chaining
🏠