ARM. STM32 швидкий старт. Швидке освоєння мікроконтролерів STM32. Взаємодія ядра з периферійним блоком

У Останніми роками 32-розрядні мікроконтролери (МК) на основі процесорів ARM стрімко завойовують світ електроніки. Цей прорив зумовлений їхньою високою продуктивністю, досконалою архітектурою, малим споживанням енергії, низькою вартістю та розвиненими засобами програмування.

КОРОТКА ІСТОРІЯ
Назва ARM є абревіатурою Advanced RISC Machines, де RISC (Reduced Instruction Set Computer) позначає архітектуру процесорів із скороченим набором команд. Переважна кількість популярних МК, а приклад сімейства PIC та AVR, також мають архітектуру RISC, яка дозволила збільшити швидкодію за рахунок спрощення декодування інструкцій та прискорення їх виконання. Поява досконалих і продуктивних 32 розрядних ARM мікроконтролерів дозволяє перейти до вирішення складніших завдань, з якими вже не справляються 8 і 16 розрядні МК. Мікропроцесорна архітектура ARM з 32-розрядним ядром та набором команд RISC була розроблена британською компанією ARM Ltd, яка займається виключно розробкою ядер, компіляторів та засобів налагодження. Компанія не виробляє МК, а продає ліцензії з їхньої виробництво. МК ARM – один з сегментів ринку МК, що швидко розвиваються. Ці прилади використовують технології енергозбереження, тому знаходять широке застосування у системах, що вбудовуються, і домінують на ринку. мобільних пристроїв, для яких важливо низьке енергоспоживання. Крім того, ARM мікроконтролери активно застосовуються в засобах зв'язку, портативних і вбудованих пристроях, де потрібна висока продуктивність. Особливістю архітектури ARM є обчислювальне ядро ​​процесора, не оснащене будь-якими додатковими елементами. Кожен розробник процесорів повинен самостійно до оснастити це ядро необхідними блокамипід свої конкретні завдання. Такий підхід добре зарекомендував себе для великих виробників мікросхем, хоча спочатку був орієнтований на класичні процесорні рішення. Процесори ARM вже пройшли кілька етапів розвитку та добре відомі сімействами ARM7, ARM9, ARM11 та Cortex. Останнє ділиться на підродини класичних процесорів CortexA, процесорів для систем реального часу CortexR та мікропроцесорні ядра CortexM. Саме ядра CortexM стали основою розробки великого класу 32 розрядних МК. Від інших варіантів архітектури Cortex вони відрізняються, перш за все, використанням 16-розрядного набору інструкцій Thumb2. Цей набір поєднував у собі продуктивність і компактність «класичних» інструкцій ARM і Thumb та розроблявся спеціально для роботи з мовами С та С++, що суттєво підвищує якість коду. Великою гідністюМК, побудованих на ядрі CortexM, є їх програмною сумісністю, що теоретично дозволяє використовувати програмний код мовою високого рівняу моделях різних виробників. Крім позначення сфери застосування ядра, розробники МК вказують продуктивність ядра CortexM за десятибальною шкалою. На сьогоднішній день найпопулярнішими варіантами є CortexM3 та CortexM4. МК з архітектурою ARMвиробляють такі компанії, як Analog Devices, Atmel, Xilinx, Altera, Cirrus Logic, Intel, Marvell, NXP, STMicroelectronics, Samsung, LG, MediaTek, MStar, Qualcomm, Sony Ericsson, Texas Instruments, nVidia, Freescale, Міландр, HiSilicon та інші.
Завдяки оптимізованій архітектурі вартість МК на основі ядра CortexM у деяких випадках навіть не менша, ніж у багатьох 8-розрядних приладів. Молодші моделі в даний час можна придбати по 30 руб. за корпус, що створює конкуренцію попереднім поколінням МК. МІКРОКОНТРОЛЕРИ STM32 Розглянемо найдоступніший і найпоширеніший МК сімейства STM32F100 від компанії STMicroelectronics, яка є одним з провідних світових виробників МК. Нещодавно компанія оголосила про початок виробництва 32-бітного МК, що використовує переваги індустріального.
ядра STM32 у недорогих додатках. МК сімейства STM32F100 Value line призначені для пристроїв, де не вистачає продуктивності 16-розрядних МК, а багатий функціонал «звичайних» 32-розрядних приладів є надлишковим. Лінійка МК STM32F100 базується на сучасному ядрі ARM CortexM3 з периферією, оптимізованою для застосування в типових додатках, де використовувалися 16-розрядні МК. Продуктивність МК STM32F100 на тактовій частоті 24 МГц перевершує більшість 16-розрядних МК. Ця лінійка включає прилади з різними параметрами:
● від 16 до 128 кбайт флешпам'яті програм;
● від 4 до 8 кбайт оперативної пам'яті;
● до 80 портів введення GPIO;
● до дев'яти 16-розрядних таймерів з розширеними функціями;
● два сторожові таймери;
● 16-канальний високошвидкісний 12-розрядний АЦП;
● два 12-розрядні ЦАП із вбудованими генераторами сигналів;
● до трьох інтерфейсів UART із підтримкою режимів IrDA, LIN та ISO7816;
● до двох інтерфейсів SPI;
● до двох інтерфейсів I2С із підтримкою режимів SMBus та PMBus;
● 7-канальний блок прямого доступу до пам'яті (DMA);
● інтерфейс CEC (Consumer Electronics Control), включений до стандарту HDMI;
● годинник реального часу (RTC);
● контролер вкладених переривань NVIC.

Функціональна схема STM32F100 представлена ​​малюнку 1.

Мал. 1. Архітектура МК лінійки STM32F100

Додатковою зручністю є сумісність приладів за висновками, що дозволяє, за потреби, використовувати будь-який МК сімейства з більшою функціональністю та пам'яттю без переробки друкованої плати. Лінійка контролерів STM32F100 виробляється в трьох типахкорпусів LQFP48, LQFP64 та LQFP100, що мають, відповідно, 48, 64 та 100 висновків. Призначення висновків представлено на рисунках 2, 3 та 4. Такі корпуси можна встановлювати на друковані плати без застосування спеціального обладнання, що є вагомим фактором при дрібносерійному виробництві.


Мал. 2. МК STM32 у корпусі LQFP48 Мал. 3. МК STM32 у корпусі LQFP64


Мал. 4. МК STM32 у корпусі LQFP100

STM32F100 – доступний та оптимізований прилад, що базується на ядрі CortexM3, підтримується розвиненим середовищем розробки МК сімейства STM32, що містить
безкоштовні бібліотеки для всієї периферії, включаючи керування двигунами та сенсорними клавіатурами.

СХЕМА ВКЛЮЧЕННЯ STM32F100C4
Розглянемо практичне використання МК на прикладі найпростішого приладу STM32F100C4, який містить всі основні блоки лінійки STM32F100. Принципова електрична схемавключення STM32F100C4 представлена ​​малюнку 5.


Мал. 5. Схема включення МК STM32F100C4

Конденсатор С1 забезпечує скидання МК під час включення живлення, а конденсатори С2-С6 фільтрують напругу живлення. Резистори R1 та R2 обмежують сигнальний струм висновків МК. Як джерело тактової частоти використовується внутрішній генератор, тому немає необхідності застосовувати зовнішній кварцовий резонатор.


Входи BOOT0 і BOOT1 дозволяють вибрати спосіб завантаження МК при включенні живлення відповідно до таблиці. Вхід BOOT0 підключений до шини нульового потенціалу через резистор R2, який оберігає виведення BOOT0 від короткого замикання при його використанні як вихідний порт PB2. За допомогою з'єднувача J1 і однієї перемички можна змінювати потенціал на вході BOOT0, визначаючи тим самим спосіб завантаження МК - з флешпам'яті або вбудованого завантажувача. При необхідності завантаження МК з оперативної пам'яті аналогічний з'єднувач із перемичкою можна підключити до входу BOOT1.
Програмування МК здійснюється через послідовний порт UART1 або через спеціальні програматори – налагоджувачі JTAG або STLink. Останній входить до складу популярного налагоджувального пристрою STM32VLDISCOVERY, зображеного на малюнку 6. На платі STM32VLDIS COVERY 4-контактний роз'єм програматора - відладчика STLink - має позначення SWD. Автор статті пропонує програмувати МК через послідовний порт UART1, оскільки це значно простіше, не вимагає спеціального обладнання та не поступається у швидкості JTAG або ST Link. Як керуючий пристрій, здатний формувати команди і відображати результати роботи програми МК, а також як програматор можна використовувати будь-який персональний комп'ютер(ПК), що має послідовний COM порт або USB-порт з перетворювачем USBRS232.

Для поєднання COMпорту ПК з МК підійде будь-якийперетворювач сигналів RS232 в рівні логічних сигналів від 0 до 3,3 В, наприклад, мікросхема ADM3232. Лінія передачі TXD послідовного портукомп'ютера, після перетворювача рівнів, повинна підключатися до входу мікроконтролера PA10, а лінія приймача RXD, через аналогічний перетворювач, - до виходу PA9.

При необхідності використання енергонезалежного годинника МК, до нього слід підключити елемент живлення типу CR2032 з напругою 3 В і кварцовий резонатор на частоту 32768 Гц. Для цього МК оснащений висновками Vbat/GND та OSC32_IN/OSC32_OUT. Попередньо висновок Vbat необхідно відключити від шини живлення 3,3 Ст.

Висновки МК, що залишилися вільними, можна використовувати за необхідністю. Для цього їх слід підключити до роз'ємів, що розташовані по периметру друкованої плати для МК, за аналогією з популярними пристроями Arduinoта налагоджувальною платою STM32VLDISCOVERY .


Мал. 6. Налагоджувальний пристрій STM32VLDISCOVERY


Схема електрична важлива STM32VLDISCOVERY.

Таким чином, залежно від призначення та способу застосування МК, до нього можна підключати необхідні елементи, щоб задіяти інші функціональні блоки та порти, наприклад, ADC, DAC, SPI, I2C тощо. Надалі ці пристрої будуть розглянуті докладніше.

ПРОГРАМУВАННЯ
Сьогодні багато компаній пропонують засоби для створення та налагодження програм мікроконтролерів STM32. До них відносяться Keil від ARM Ltd, IAR Embedded Workbench for ARM, Atol lic TrueStudio, CooCox IDE, GCC та Eclipse IDE. Розробник може вибрати програмні засоби за своєю повагою. Нижче буде описаний інструментарій Keil uVision 4 від компанії Keil, який підтримує величезну кількість типів МК, має розвинену систему налагоджувальних засобів і може бути використаний безкоштовно з обмеженнями розміру коду, що генерується 32 кбайт (що, фактично, максимально для розглянутих МК).

Простий та швидкий старт з CooCox CoIDE.

Тож приступимо. Ідемо на офіційний сайт CooCox і качаємо останню версію CooCox CoIDE. Для скачування необхідно зареєструватися, реєстрація проста та безкоштовна. Потім встановлюємо завантажений файл і запускаємо.

CooCox CoIDE— середовище розробки, на базі Eclipse, яке, крім STM32, підтримує купу інших сімейств мікроконтролерів: Freescale, Holtek, NXP, Nuvoton, TI, Atmel SAM, Energy Micro та ін. З кожною новою версією CoIDE список МК постійно поповнюється. Після успішного встановлення CoIDE запускаємо:

З'явиться стартове вікно Step 1, в якому потрібно обрати виробника нашого мікроконтролера. Натискаємо ST та переходимо до Step 2 (вибір мікроконтролера), у якому необхідно вибрати конкретну модель. У нас STM32F100RBT6B, тому натискаємо на відповідну модель:

Праворуч, у вікні Help відображаються короткі характеристикикожного чіпа. Після вибору потрібного мікроконтролера переходимо до третього кроку Step 3 — до вибору необхідних бібліотекдля роботи:

Давайте створимо найпростіший проект для миготіння світлодіодом, як це заведено для вивчення мікроконтролерів.

Для цього нам знадобиться бібліотека GPIO, при включенні якої CoIDE попросить створити новий проект. На цю пропозицію натискаємо Yes, вказуємо папку, де буде зберігатися наш проект та його назва. При цьому, CoIDE підключить до проекту 3 інші необхідні для роботи бібліотеки, а також створить всю необхідну структуру проекту:

Чим ще хороший CoIDE, це тим, що в ньому є можливість завантажувати приклади безпосередньо в середу розробки. У вкладці Components можна побачити, що майже до кожної бібліотеки є приклади, натискаємо на GPIO (with 4 examples) і бачимо їх:

Туди можна додавати свої приклади. Як видно на скріншоті вище, у прикладах вже є код для миготіння світлодіодом GPIO_Blink. Можна натиснути кнопку add і він додатися в проект, але як файл, що підключається, тому ми зробимо інакше просто скопіюємо весь код прикладу в файл main.c. Єдине, що рядок void GPIO_Blink(void) замініть на int main(void). Отже, натискаємо F7 (або в меню вибираємо Project->Build), щоб скомпілювати проект і ... не тут було!

Серед потрібен компілятор GCC, А в нас його немає. Тому йдемо на сторінку GNU Tools for ARM Embedded Processors, праворуч вибираємо тип вашої ОС і качаємо останню версію тулчайну. Потім запускаємо файл та встановлюємо gcc toolchain. Далі, в налаштуваннях CoIDE вкажемо правильний шлях до тулчайну:

Знову натискаємо F7 (Project->Build) і бачимо, що компіляція пройшла успішно:

Залишилося прошити мікроконтролер. Для цього при допомоги USBпідключаємо нашу плату до комп'ютера. Потім в налаштуваннях дебаггера необхідно поставити ST-Link, для цього в меню вибираємо Project->Configuration і відкриваємо вкладку Debugger. У списку вибираємо ST-Link і закриваємо вікно:

Спробуємо прошити МК. У меню вибираємо Flash->Program Download (або на панелі інструментів клацаємо по відповідній іконці) і бачимо, що МК успішно прошить:

На платі спостерігаємо миготливий світлодіод, відео чи фото я думаю наводити немає сенсу, тому що. все це бачили.

Також, у CoIDE працюють різні режиминалагодження, для цього натискаємо CTRL+F5 (або в меню Debug->Debug):

На цьому все. Як бачите, налаштування середовища CoIDE і робота з нею дуже проста. Сподіваюся, ця стаття підштовхне вас у вивченні дуже перспективних і недорогих мікроконтролерів STM32.

Опубликовано 09.08.2016

Мікроконтролери STM32набувають все більшої популярності завдяки своїй потужності, досить різнорідній периферії, і своїй гнучкості. Ми почнемо вивчати, використовуючи бюджетну тестову плату, вартість якої не перевищує 2$ (у китайців). Ще нам знадобиться ST-Linkпрограматор, вартість якого близько 2.5$ (у китайців). Такі суми видатків доступні і студентам та школярам, ​​тому саме з такого бюджетного варіанту я і пропоную розпочати.


Цей мікроконтролер не є найпотужнішим серед STM32але й не найслабший. Існують різні платиз STM32, у тому числі Discoveryякі за ціною коштують близько 20$. На таких платах майже все те, що і на нашій платі, плюс програматор. У нашому випадку ми використовуватимемо програматор окремо.

Мікроконтролер STM32F103C8. Характеристики

  • Ядро ARM 32-bit Cortex-M3
  • Максимальна частота 72МГц
  • 64Кб Флеш пам'ять для програм
  • 20Кб SRAM пам'яті
  • Харчування 2.0 … 3.3В
  • 2 x 12-біт АЦП (0...3.6В)
  • DMA контролер
  • 37 входів/виходів толерантних до 5В
  • 4 16-розрядні таймери
  • 2 watchdog таймера
  • I2C – 2 шини
  • USART – 3 шини
  • SPI – 2 шини
  • USB 2.0 full-speed interface
  • RTC – вбудований годинник

На платі STM32F103C8 доступні

  • Виводь портів A0-A12, B0-B1, B3-B15, C13-C15
  • Micro-USBчерез який можна живити плату. На платі є стабілізатор напруги на 3.3В. Харчування 3.3 або 5В можна подавати на відповідні висновки на платі.
  • Кнопка Reset
  • Дві перемички BOOT0і BOOT1. Будемо використовувати під час прошивки через UART.
  • Два кварці 8МГц та 32768 Гц. У мікроконтролера є множник частоти, тому на кварці 8 МГц ми зможемо досягти максимальної частотиконтролера 72МГц.
  • Два світлодіоди. PWR– сигналізує про подачу живлення. PC13– підключено до виходу C13.
  • Конектор для програматора ST-Link.

Отже, почнемо з того, що спробуємо прошити мікроконтролер. Це можна зробити за допомогою через USART, або за допомогою програматора ST-Link.

Завантажити тестовий файл для прошивки можна. Програма блимає світлодіодом на платі.

Прошивка STM32 за допомогою USB-Uart перехідника під Windows

У системній пам'яті STM32є Bootloader. Bootloader записаний на етапі виробництва та будь-який мікроконтролер STM32можна запрограмувати через інтерфейс USARTза допомогою USART-USB перехідника. Такі перехідники найчастіше виготовляють на базі популярної мікросхеми. FT232RL. Перш за все підключимо перехідник до комп'ютера та встановимо драйвера (якщо потрібно). Завантажити драйвера можна з сайту виробника FT232RL- ftdichip.com. Треба качати драйвера VCP(Virtual com port). Після інсталяції драйверів на комп'ютері з'явиться віртуальний послідовний порт.


Підключаємо RXі TXвиходи до відповідних висновків USART1мікроконтролера. RXперехідника підключаємо до TXмікроконтролера (A9). TXперехідника підключаємо до RXмікроконтролера (A10). Оскільки USART-USB має виходи живлення 3.3В подамо харчування на плату від нього.

Щоб перевести мікроконтролер у режим програмування, треба встановити висновки BOOT0і BOOT1в необхідний станта перезавантажити його кнопкою Resetабо вимкнути та включити живлення мікроконтролера. Для цього ми маємо перемички. Різні комбінації заганяють мікроконтролер у різні режими. Нас цікавить лише один режим. Для цього у мікроконтролера на висновку BOOT0має бути логічна одиниця, а на висновку BOOT1- Логічний нуль. На платі це таке положення перемичок:

Після натискання кнопки Resetабо вимкнення та підключення живлення, мікроконтролер повинен перейти в режим програмування.

Програмне забезпечення для прошивки

Якщо використовуємо USB-UART перехідник, ім'я порту буде приблизно таке /dev/ttyUSB0

Отримати інформацію про чіп

Результат:

Читаємо з чіпа у файл dump.bin

sudo stm32flash -r dump.bin /dev/ttyUSB0

Пишемо в чіп

sudo stm32flash -w dump.bin -v -g 0x0 /dev/ttyUSB0

Результат:

Stm32flash 0.4 http://stm32flash.googlecode.com/ Using Parser: Raw BINARY Interface serial_posix: 57600 8E1 Version: 0x22 Option 1: 0x00 Option 2: 0x00 Device ID: 0x0410 (Medium-den bootloader) - Flash: 128KiB (sector size: 4x1024) - Option RAM: 16b - System RAM: 2KiB Завантажити пам'яту Erasing memory Wrote and verified address 0x08012900 (100.00%) Done. Starting execution at address 0x08000000... done.

Прошивка STM32 за допомогою ST-Link програматора під Windows

При використанні програматора ST-Linkвисновки BOOT0і BOOT1не використовуються і повинні стояти в стандартному положеннідля нормальної роботиконтролера.

(Книжка російською мовою)

Маркування STM32

Device familyProduct typeDevice subfamilyPin countFlash memory sizePackageTemperature range
STM32 =
ARM-based 32-bit microcontroller
F = General-purpose
L = Ultra-low-power
TS = TouchScreen
W = Wireless system-on-chip
60 = multitouch resistive
103 = performance line
F = 20 pins
G = 28 pins
K = 32 pins
T = 36 pins
H = 40 pins
C = 48/49 pins
R = 64 pins
O = 90 pins
V = 100 pins
Z = 144 pins
I = 176 pins
B = 208 pins
N = 216 pins
4 = 16 Kbytes of Flash memory
6 = 32 Kbytes of Flash memory
8 = 64 Kbytes of Flash memory
B = 128 Kbytes of Flash memory
Z = 192 Kbytes of Flash memory
C = 256 Kbytes of Flash memory
D = 384 Kbytes of Flash memory
E = 512 Kbytes of Flash memory
F = 768 Kbytes of Flash memory
G = 1024 Kbytes of Flash memory
I = 2048 Kbytes of Flash memory
H = UFBGA
N = TFBGA
P = TSSOP
T = LQFP
U = V/UFQFPN
Y = WLCSP
6 = Industrial temperature range –40…+85 °C.
7 = Industrial temperature range, -40…+105 °C.
STM32F103 C8 T6

Як зняти захист від запису/читання?

Якщо ви отримали плату із STM32F103, а програматор її не бачить, це означає, що китайці захистили Флеш пам'ять мікроконтролера. Питання "навіщо?" залишимо поза увагою. Щоб зняти блокування, підключимо UART перехідник, програмуватимемо через нього. Виставляємо перемички для програмування та поїхали:

Я це робитиму з-під Ubuntu за допомогою утиліти stm32flash.

1. Перевіряємо чи видно мікроконтролер:

Sudo stm32flash /dev/ttyUSB0

Повинні отримати щось таке:

Stm32flash 0.4 http://stm32flash.googlecode.com/ Interface serial_posix: 57600 8E1 Version: 0x22 Option 1: 0x00 Option 2: 0x00 Device ID: 0x0410 (Medium-density) 128KiB (sector size: 4x1024) - Option RAM: 16b - System RAM: 2KiB

2. Знімаємо захист від читання, а потім від запису:

Sudo stm32flash -k /dev/ttyUSB0 stm32flash 0.4 http://stm32flash.googlecode.com/ Interface serial_posix: 57600 8E1 Version: 0x22 1: 0x00 Option 2: 0x00 Device ID: 0 512b reserved by bootloader) - Flash: 128KiB (sector size: 4x1024) - Option RAM: 16b - System RAM: 2KiB Read-UnProtecting flash Done. sudo stm32flash -u /dev/ttyUSB0 stm32flash 0.4 http://stm32flash.googlecode.com/ Interface serial_posix: 57600 8E1 Version: 0x22 1: 0x00 Option 2: 0x00 Device ID: 0 512b reserved by bootloader) - Flash: 128KiB (sector size: 4x1024) - Option RAM: 16b - System RAM: 2KiB Write-unprotecting flash Done.

Тепер можна нормально працювати із мікроконтролером.

Мікроконтролери для кошенят

Всім Мяу, катани:)

Якось від мене пішла кішка: (Ну і чим валеріанку лопати, я вирішив зайнятися справою, так би мовити «на благо Батьківщині». Давно вже хотів цифровими пристроями зайнятися, та часу не було (самі розумієте, то спати, то з кішкою) по дахах гуляти), а тут якраз час і з'явилося. Ну-з почнемо.

Все як завжди починається з вибору. Ну начебто вибір невеликий PIC, та AVR. Останні мені якось більше сподобалися. Потрібен був ще й USB програматор через відсутність інших портів на комп'ютері, від ціни якого у мене ледь хвіст не відвалився. Ще Arduino є - звірятко таке. Його і програмувати USB можна. Ну, думаю, "те що лікар прописав". У селі його тільки через інтернет-магазин дістати можна. Знайшов, де по-вигідно, мало не купив і... ОПА! Дивлюсь - STM32VL-Discovery. Що за звір такий? Хм, STM32.. Щось чув краєм вуха.. А від характеристик вуса дибки, чесно!

А лап у неї скільки!

Отже, поряд:

  • Arduino має 14 цифрових портів введення/виводу і 6 аналогових входів. У STM32VL-Discovery 45 цифрових входу/виходу 10 з яких за бажанням перетворюються на аналогові входи.
  • Arduino має 32 Кб для зберігання програми і 2 Кб ОЗУ. STM32VL-Discovery має 64 Кб для зберігання програм і 8 Кб ОЗУ.
  • У Arduino тактова частота 16 МГц у STM32VL-Discovery ж 24 МГц.
  • Будь-який мікроконтролер STM32 можна замінити іншим STM32, але з кращими характеристикамибез зміни схеми
  • STM32 можна програмувати без програматора по COM порту(Про це трохи пізніше)
  • Ціна Arduino на момент написання статті ~ 1300 рублів, STM32VL-Discovery ~ 600 рублів. Це дешевше більше ніж у 2 рази!

А що далі? У STM32VL-Discovery є вбудований програматор/наладчик, який легким рухом лапи (зняттям перемичок) може програмувати і налагоджувати (налагодження дуже річ корисна, але про це трохи пізніше) мікроконтролери STM32 за межами плати. З Arduino таке не прокотить. Тобто використовуючи STM32VL-Discovery ми і гроші заощаджуємо і отримуємо більшу продуктивність та свободу творчості:)

Та й самі мікроконтролери STM32 виглядають привабливіше за інших:

STM32F100C4T6B ATtiny24A-SSU PIC16F688-I/SL STM32F103RET6 ATmega1284P-PU PIC18F4550-I/PT
Середня ціна, руб 60 65 60 240 330 220
Тактова частота, МГц 24 20 20 72 20 48
Flash пам'ять, Кбайт 16 2 4 512 128 16
RAM, Байт 4096 128 256 65536 16384 2048
USART, шт 2 0 0 5 2 0
SPI, шт 1 1 0 3 1 1
АЦП, шт 16x12Bit 8x10Bit 8x10Bit 16х12Bit 8x10Bit 13x10Bit
ЦАП, шт 1x12Bit 0 0 2х12Bit 0 0
Кількість ліній введення/виводу, шт 37 12 12 51 32 35

А ще STM32 32-розрядні, а це означає можливість роботи з 32-бітними даними за один такт. AVR та PIC цим не похваляються.

Ну що, катани, переконав? Тоді почнемо курс молодого бійця цифровика!)

Як воно працює? З чого складається? Що вміє?

Як відомо, всі коти дуже допитливі, а радіокоти особливо!

Мікроконтролер - це мікросхема, що поєднує в собі функції процесора, периферії, що має ОЗУ, flash пам'ять. Як комп'ютер лише менше!

Проведемо аналогію: комп'ютером керує операційна системаа мікроконтролером «прошивка», яку пишете Ви; операційна система комп'ютера зберігається на жорсткому диску, «прошивка» мікроконтролера у його flash пам'яті; функції ОЗУ схожі - зберігання даних, що змінюються під час виконання програми. А ще МК має різні периферійні пристрої, такі як АЦП і ЦАП наприклад.

МК спілкується із зовнішнім світом за допомогою лап на його корпусі (не таких як у котів, звичайно, а металевих). Але не всі з них керуються програмою, є висновки харчування, висновок скидання, висновки харчування периферії, висновок резервного харчування. А ті, що керуються програмою, поділяються на групи звані «порти». Всі ці керовані висновки називаються двома літерами та цифрою. Наприклад PA1: P – порт, А – порт «А», 1 – номер виведення цього порту.

У програмі порти конфігуруються або вхід, або вихід, за вашим бажанням.

Висновки порту налаштованого на вхід можуть бути в різних режимахдля кожного висновку він може бути своїм:

  • Цифровий вхід - вхід, значення якого (логічна 1 чи 0) можна зчитувати програмою. Якщо нап'яження на вході 0, то значення дорівнює 0, якщо на вході напяження дорівнює напряденню живлення, значення входу 1. Третього не дано. Можна зробити з підтягуючим резистором або до харчування, або до маси
  • Аналоговий вхід - вхід значення якого можна зчитувати програмою, але значень може бути багато - цілих 4096. А точніше від 0 якщо на вході напряження 0 щодо мінуса живлення мікроконтролера до 4095, якщо на вході напруга дорівнює напруги живлення. Всі ці перетворення робить АЦП - аналогово-цифровий перетворювач, за допомогою його можна, наприклад, вимірювати напругу на терморезисторі і впізнавати температуру або вимірювати напруження на фоторезисторі і впізнавати яскравість світла, що потрапляє на нього... Ну багато чого можна придумати, якщо фантазія є:) Якщо живити мікроконтролер від 3В, то 0В = 0, а 3В = 4096, отже 3/4096=0.000732421, тобто. при зміні напруження на вході на 0.000732421В значення входу в програмі змінюється на 1. Не так все і складно, так? Йдемо далі
  • Цифровий вхід у режимі альтернативної функції - вхід до роботи з периферією. Наприклад, вхід для таймера або вхід для якогось інтерфейсу. З програми значення цього входу вважати не можна. У програмі можна вважати дані отримані з цього висновку яким-небудь інтерфейсом.

А у порту налаштованого на вихід висновки можуть бути в таких режимах:

  • Вихід. Просто вихід. Звичайний цифровий вихід. На виведенні чи напрядіння живлення (логічна 1) чи виведенні немає напруги (логічна 0). Все просто.
  • Вихід у режимі альтернативної функції - вихід керований периферією. Цим виходом не можна керувати з програми, але програмою можна змусити керувати цим висновком, наприклад, інтерфейс.

Але не всі висновки можна призначати «як заманеться». Для того, щоб дізнатися, що можна, а що не можна подивитися документацію (таблиця 4) або скористатися програмою MicroXplorer.

Перед використанням порту потрібно спочатку тактувати - подавати нею тактові імпульси, т.к. спочатку вони не подаються для економії енергії. Можна вибрати різну частоту тактування - більше частота - швидше працюють входи чи виходи цього порту, а й більше споживання енергії.

Ще є висновки BOOT 0і BOOT 1. Ці висновки не стосуються портів, вони служать керувати завантаженням микроконтроллера. Якщо під час подачі живлення на виведенні BOOT 0 логічний нуль (висновок з'єднаний із загальною точкою), то мікроконтролер виконує програму, завантажену у flash пам'ять, тобто. Вашу прошивку. Якщо під час подачі живлення на виводі BOOT 0 логічна одиниця (висновок з'єднаний з живленням мікроконтролера), а на виведенні BOOT 1 логічний нуль, то мікроконтролер виконує не вашу прошивку, а записаний на заводі завантажувач. Запам'ятайте це! Ви часто будете користуватися цим у процесі роботи з мікроконтролерами STM32!Іноді завантаження записаного із заводу завантажувача - єдиний спосібзаписати/змінити прошивку мікроконтролера. Це буває, наприклад, при конфігуруванні в прошивці висновків, до яких підключається програматор або при прошивці мікроконтролера без використання програматора. Так що наполегливо рекомендуюпри проектуванні друкованої плати ці висновки (або хоча б BOOT 0) розміщувати у зручному місці.

Ось розібралися:) Тепер знаємо, що таке мікроконтролер, з чого він складається. Зараз дізнаємося ще про деякі премудрості і перейдемо до найцікавішого – практики!

Програма у мікроконтролері виконується покроково. Один такт процесора – один крок програми.

Наприклад нехай переморгується червона та зелена лампочки, поки не натиснута кнопка. Тривалість кожної лампи – 5 секунд. Ось алгоритм:

  1. Перевіряємо, чи на вході з кнопкою є напруга? (кнопка замикає виведення мікроконтролера на + живлення)
  2. Якщо немає напруги, то спалахує червона лампочка на 5 секунд, зелена тухне, якщо є напруга, то починаємо все спочатку
  3. Знову перевіряємо
  4. Якщо немає напруги, то спалахує зелена лампочка на 5 секунд, червона тухне, якщо є напруга, то починаємо все спочатку
  5. Починаємо спочатку

СТОП! А якщо я натисну кнопку, доки горить лампочка? То нічого не станеться! Тому що програма виконується крок за кроком, а крок з перевіркою натискання кнопки знаходиться в момент перемикання лампочок.
Саме для таких випадків є така річ, як переривання

Переривання дозволяють перервати виконання основної програми. Зробити це можна або зовнішньою подією (натискання кнопки, відпускання кнопки прийом даних тощо) або внутрішньою (за таймером або настав час годувати кота наприклад). Коли відбувається це саме переривання, починає виконуватися підпрограма. Підпрограми можуть бути різні для різних видів переривань, ці підпрограми називаються обробники переривання.

Коли цей обробник переривання закінчить свою роботу, основна програма починає виконуватися з того місця, де була перервана.

Стаємо на лапи!

Ну, кошенята, настав час вставати на лапи! Сподіваюся, у Вас вже є налагоджувальна плата? Чи хоча б мікроконтролер? Сподіваюся їсти:) А якщо ні, то біжимо до магазину! (і бажано не за ковбасою. хоч...) Яке ж це вчення без практики?

Відмінно спочатку мати налагоджувальну плату, наприклад STM32VL-Discovery, але якщо жаба душить або все-таки бракує на ковбасу, то можна обійтися і одним мікроконтролером і перетворювачем інтерфейсів RS-232 -> UART (напр. MAX3232) або USB -> UART (Напр. FT232RL). В цьому випадку в 100 рублів можна цілком вкластися, але доведеться робити друковану плату і паяти мінімум 48 висновків шириною 0,3 мм із зазором 0,2 мм. Я попереджував.

Спочатку потрібно природно прикошачить налагоджувальну плату або контролер до комп'ютера.

Якщо у Вас налагоджувальна плата:

З налагоджувальною платою, звичайно, простіше. Беремо шнурок Mini-USB і з'єднуємо плату з комп'ютером, всі драйвери повинні поставлятися автоматично. Побачити STMicroelectronics STLink dongleу диспетчері пристроїв - добрий знак! Ну а якщо щось пішло не так і нічого не вийшло – не треба дряпати диван, потрібно просто зайти сюди та встановити STM32 ST-LINK utility.

Ну а якщо Ви щасливий власник комп'ютера під керуванням Windows 8, перед проведенням вищеописаних дій потрібно зробити так: Параметри -> Зміна параметрів комп'ютера -> Загальні -> Особливі варіанти завантаженнята вибрати параметр Вимкнення перевірки підпису драйверів.

Якщо у Вас мікроконтролер:

Якщо у вас один мікроконтролер, то у вас повинні бути прямі лапи. Але я у Вас не сумніваюся!

Перед підключенням мікроконтролера до комп'ютера потрібно припаяти до друкованої плати. Для цього, крім мікроконтролера і прямих лап, потрібна як мінімум друкована плата. А тут уже ваша творчість.

Робочий мінімум на схемі нижче:

Але це нецікавий мінімум.

Додайте світлодіодів та кнопок (не забудьте про висновки BOOT), наприклад так

А ось із паянням цієї блохи можуть виникнути проблеми. Але я сподіваюся, що не виникнуть. Я накошачився паяти її своїм улюбленим радянським 25 Вт паяльником із шириною жала в 3/4 ширини контролера. У мене більше проблемз виготовленням друкованої плати... ну тут у кожного вже своя технологія.

І перехідник потрібно зробити на UART документації до тієї мікросхеми, яку купили.

З'єднуємо висновки TxD та RxD на друкованій платі з висновками RxD та TxD відповідно перехідника. Не забуваємо про загальну точку та харчування всього цього.

Вибір та встановлення ПЗ

Користуватися ми будемо середовищем розробки CooCox IDE, але це не просто так, а з кількох причин:

  • По-перше, це вільно розповсюджуване ПЗ. А це означає, що Ваша карма буде чистою
  • На мій погляд (та й не тільки на мій) це середовище розробки зручніше за решту
  • Дозволяє використовувати налагодження
  • Багато прикладів, які можна завантажувати в середу розробки (корисно для кошенят і не тільки)

Середовище розробки - це програма для написання коду, компілятора, відладчика в одному. Але якщо якомусь суворому Челябінському коту зручніше писати код (у блокноті наприклад), компілювати і прошивати різними програмами - я не проти, тоді Вам знадобиться STM32 ST-LINK utilit для завантаження прошивки в мікроконтролер. Хазяїн пан, як то кажуть.

Це середовище розробки засноване на багатьох відомих Eclipse.

  1. Ідемо сюди
  2. Тикаємо Download через CoCenter (Recommend)
  3. Вводимо адресу ел.пошти (можна від балди, вона там «для галочки»)
  4. Після завантаження встановлюємо цей самий CoCenter
  5. У першому рядку, де написано CooCox CoIDEтикаємо Download
  6. Після того, як завантаження закінчиться, то замість Downloadбуде Install. Сюди і тиснемо
  7. Ідемо сюди
  8. Праворуч у колонці Downloadзавантажуємо файл який .exe.Встановлюємо його.
  9. Відкриваємо сам CooCox CoIDE, вкладка Project, Select Toolchain Path.
  10. Вказуємо шлях до файлу arm-none-eabi-gcc.exe (це ми встановили п.8, шлях приблизно такий: D:Program Files (x86)GNU Tools ARM Embedded4.7 2013q1bin)
  11. Знову відкриваємо CoIDE, натискаємо View -> Configuration, відкриваємо вкладку Debuggerі робимо так [фото]
  12. Радіємо, тому що тепер ми можемо написати програму та прошити її у мікроконтролер! Чим ми займемося.

Якщо у Вас варіант без налагоджувальної плати/програматора, то для завантаження програми в МК знадобиться програма Flash Loader Demonstratorяка знаходиться

Знаходимо спільну мову

Перед тим, як писати свою першу програму, потрібно знайти з МК спільну мову. Навряд чи він буде вчити нашу мову, тому доведеться вивчити (а може просто згадати) мову якою ми будемо спілкуватися з МК, це Сі. Знадобляться лише основи (склад програми, функції, оператори). Якщо мову цю знаєте, можете відразу перейти до пункту «Перша програма», ну а незнаючих я введу в курс справи.

Проект складається з файлів із розширеннями .cі .h. У перших знаходяться функції у других назви використовуваних функцій та константи, наприклад. Так уже заведено. Найголовніший файл, у якому знаходиться код програми main.c. Для використання різних функційНеобхідно підключати бібліотеки з цими функціями. Підключаються вони записом #include "назва_бібліотеки"Ну бібліотеки природно повинні бути в проекті. Підключають їх на самому початку файлу.

Функції – це своєрідна частина програми. Взагалі програма складається з однієї чи кількох функцій. Функція має вигляд:

тип_повертається_змінної ім'я_функції (тип_змінної)
{
Тіло функції
}

У функцію можна відправити якусь змінну, функція її обробить і поверне якесь значення. Дуже зручно використовувати функцію для повторюваних дій, ніж писати постійно один і той же шматок коду, можна просто відправляти змінну в функцію і отримувати оброблене значення.

Перед тим, як використовувати функцію, її потрібно оголосити на початку файлу. Роблять це у такому вигляді:

тип_повертається_змінної ім'я_функції (тип_змінної);

Ах, так, забув найголовніше! Наприкінці кожного рядка має бути крапка з комою!

Якщо функція нічого не повертає (наприклад, тимчасова затримка, вона просто тягне кота за хвіст час), то тип вказують void.

При запуску першою завжди виконується функція main().

Ну з функціями начебто розібралися, розуміння прийде лише з практикою.

Вище я згадував тип змінної. Усі змінні можуть бути різних типів, ось основні:

  • INT - змінна цього може бути лише цілим числом від -2147483648 до 2147483647
  • FLOAT - змінна цього типу з точністю до 7 розрядів від ±1,5*10-45 до ±3,4*1033
  • DOUBLE – число з точністю до 16 розрядів від ±5*10-324 до ±1,7*10306
  • ULONG - теж ціле число, але від 0 до 18446744073709551615
  • LONG - ціле від -9223372036854775808 до 9223372036854775807
  • CHAR – один символ
  • BOOL – логічна змінна. Вона може мати лише 2 значення: істина (true) чи брехня (false)

Рядок (слово, пропозиція) можна представити як масив із символів типу char. Наприклад:

char stroka = "Слово";

Тут квадратних дужках – кількість символів у рядку, «stroka» – назва масиву.

Перед використанням змінної потрібно обов'язково оголосити. (просто вказати тип змінної та ім'я)

  • + - Додавання.
  • - - віднімання.
  • * - множення.
  • / - Розподіл.
  • = - Присвоєння змінної значення.

Наприклад вираз a=b+cзначить привласнити змінну aзначення суми значень змінних bі c.

  • ++ - Інкремент. Збільшення значення змінної на 1
  • -- - Декремент. Зменшення значення змінної на 1

Наприклад вираз a++означає збільшити значення змінної aна 1 (те саме, що і a=a+1)

  • == - Порівняння, знак «рівно». (Не плутати з присвоєнням)
  • != - Порівняння, знак «не дорівнює».
  • < - Порівняння, знак «менше».
  • <= - Порівняння, знак «менше або одно».
  • > - Порівняння, знак «більше».
  • >= - Порівняння, знак «більше або одно».

Наприклад вираз a стає істинним, якщо значення змінної aменше значення змінної bі помилковим, якщо значення дорівнюють або aбільше b. Вираз a==bістинно якщо aодно bі хибно, якщо aне дорівнює b, АЛЕ вираз a=bістинно завжди, тому що це не порівняння, це присвоєння змінної aзначення змінної b.

  • % - залишок від ділення

Наприклад, якщо a=5,b=3, то значення виразу a%bдорівнюватиме 2 (т.к. 5/3=1 (зуп.2))

  • << - Побітове зрушення вліво. Не вдаючись до подробиць значення виразу a<мовою Сі дорівнюватиме виразу a*2 b
  • >> - побитовий зсув праворуч. Вираз a>>bу програмі рівносильно виразу a/2 b
  • & - Логічне І.
  • | - Логічне АБО.
  • ~ - інвертування.

Мало не забув розповісти про цикли. Основні:

while (умова) (

тіло циклу

Тіло циклу (все що в фігурних дужках) виконується, коли умова істинна (поки умова стане хибним).

for (початкове значення, цикл виконується до, крок) (

тіло циклу

Початкове значення- Початкове значення лічильника

Цикл_виконується_до -до досягнення якого значення виконується цикл

Крок -з яким кроком лічильник вважає

Наприклад

for (i=0; i<10, i++) {

тіло циклу

Тут початкове значення змінної iдорівнює 0, цикл виконується, поки значення змінної iменше 10 при кожному виконанні циклу до змінної iдодається 1. Також можна змінювати значення змінної у циклі.

if (умова)(

тіло 1

) else (

тіло 2

В усовному переході «тіло 1» виконується, якщо умова істинна і виконується «тіло 2», якщо умова є хибною. Ще є такий варіант:

if (умова 1) (

) else if (умова 2) (

У цьому випадку "тіло 1" виконується, якщо істинно "умова 1", "тіло 2" виконується, якщо істинно "умова 2". Таких умов може бути скільки завгодно, так само може бути один else.

Умови можуть бути простими і складовими: прості - один логічний вираз, а складовий - кілька логічних виразів з'єднаних знаком & (умови істинно, коли всі умови, з'єднані цим знаком, істинні) або | (Умова істинна, якщо хоча б одна умова з'єднана цим знаком істинно).

Ще корисна річ – коментарі. Допоможуть розібратися в забутому проекті:) або просто щось не забути. Коментувати можна чи після знаків // і до кінця рядка або починаються знаками /* і закінчуються */ , у такому разі коментар може бути будь-якою кількістю рядків. На розмір програми коментарі не впливають.

Ну ось, з основного начебто все. Спочатку вистачить (до написання наступної частини статті)

Перша програма

Не відступатимемо від традицій (а то мало) і почнемо з Hello World. А по дорозі продовжуватимемо знайомитися з мікроконтролером і отримувати досвід.

Відкриваємо середовище розробки:

Натискаємо Browse in Repository

Вибираємо ST

Потім ми побачимо список бібліотек, що підключаються.

Для нашої простенької програми нам знадобиться: CMSIS core, CMSIS Boot, RCC, GPIO.

Бібліотеки CMSIS coreі CMSIS Boot -системні, їх потрібно обов'язково підключати

Бібліотека RCCдля роботи із системою тактування

Бібліотека GPIOдля роботи з портами вводу-виводу

Тепер ліворуч у вікні Projectвідкриваємо файл main.c.

Спочатку потрібно підключити наші бібліотеки (CMSIS не потрібно підключати).

Ідемо на початок програми і додаємо рядки:

#include "stm32f10x_gpio.h"
#include "stm32f10x_rcc.h"

void Delay (int i) (
for (; i! = 0; i--);
}

Так. Тут по порядку, функція нічого не повертає, тому void, назва функції Delayодразу оголошуємо змінну iтипу int. У фігурних дужках тіло функції - цикл for. Це його малий запис. Початкове значення iми не змінюємо, цикл виконується, поки iне дорівнює нулю (як iстає дорівнює нулю, цикл припиняється, функція «вимикається»). З кожним виконанням тіла циклу (тактом) змінна iзменшується на 1. Тобто. суть циклу - просто повторитися кількість разів рівне i. Поки виконується цикл часу, відбувається затримка.

Який порт відповідальний за який висновок можна переглянути в документації до МК:

Для тактування порту С додаємо рядок:

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);

Додаємо в прогарму рядок:

GPIO_InitTypeDef GPIO_Init1;

Цим рядком ми оголосили структуру GPIO_InitTypeDef- дали їй назву GPIO_Initдля використання у нашій програмі далі.

Які в цій структурі можна налаштувати параметри і який вигляд вони мають, дивимося все в тому ж stm32f10x_gpio.h:

Тепер, щоб налаштувати параметри висновків за допомогою структури, потрібно написати її назву, поставити крапку і з'явиться віконце в якому ці параметри вказані

Двічі клацаємо по одному з них, і він з'являється в рядку, далі ставимо = (Присвоїти) і прописуємо значення з stm32f10x_gpio.h

Так само чинимо з усіма параметрами. Не забуваємо крапку з комою наприкінці кожного рядка!

GPIO_Init(GPIOC, &GPIO_Init);

Тепер блиматимемо! Блимати ми будемо циклічно, зробимо зациклювання у циклі while.Умова циклу буде 1. Одиниця - завжди істина, нуль - завжди брехня.. така се ля ви..

Щоб подати струм на вивід, потрібно встановити біт, щоб вимкнути висновок потрібно скинути біт. Як це робити - все в тому ж stm32f10x_gpio.h:

Робимо так:

while (1)(

GPIO_SetBits(GPIOC, GPIO_Pin_9);

Delay (200 000);

GPIO_ResetBits(GPIOC, GPIO_Pin_9);

Delay (200 000);

1 завжди істина, значить цикл буде зациклювання.

GPIO_SetBits - функція встановлення біта

GPIO_ResetBits - функція скидання біта

Delay (200000) - на цьому рядку виконання програми переходить у функцію Delay, в ту саму, в якій цикл for. Число 200000 у дужках - передається в цю функцію, як змінна i. (Пам'ятаємо рядок void Delay(int i)?) і виконується цей цикл в цій функції, всі 200000 разів. Це швидко:) після закінчення роботи циклу forфункція Delayзакінчує свою роботу, т.к. вона void, то вона нічого не повертає і програма продовжує виконуватись далі.

Т.к. whileзациклений, то включення світлодіода, затримка, вимикання світлодіода, затримка виконуватиметься нескінченно циклічно. Поки не вимкнеться харчування або не станеться переривання (про це у наступній статті).

Ну ось перша програма готова. Тепер натискаємо F7, програма компілюється.

Тепер якщо у Вас налагоджувальна плата, то підключаємо її за допомогою USB шнурка та натискаємо Download Code To Flash. Радіємо виконаній роботі та отриманим знанням:)

А якщо у Вас не налагоджувальна плата, підключіть до своєї плати перехідник зроблений раніше, а перехідник до COM-порту комп'ютера. Далі з'єднайте висновок BOOT 0 c плюсом живлення мікроконтролера та увімкніть живлення мікроконтролера. Тим самим мікроконтролер увійде до режиму прошивки. Загалом процедура прошивки не складна. Потрібно просто дотримуватися вказівок програми Flash Loader Demonstrator. Спочатку вказуємо номер COM-порту, через який у Вас підключений мікроконтролер та швидкість. Для уникнення збоїв, швидкість краще вибрати поменше

Якщо програма побачила Ваш мікроконтролер, з'явиться вікно, в якому буде написано, скільки в нього пам'яті

Після натискання «Next» Ви побачите сторінку з адресацією пам'яті. Вона нам не знадобиться.

Наступний крок – найвідповідальніший. Можна вибрати чищення пам'яті або прошивку

Для прошивки вибираємо Download to deviceі в полі Download from fileвибираємо компільований.hex файл, який знаходиться в папці CooCox -> CooIDE -> workspace -> ім'я_проекту -> ім'я_проекту -> Debug -> Bin. Після цього знову натискаємо «Next».

Після того, як побачимо таке вікно:

Відключаємо живлення мікроконтролера, закриваємо Flash Loader Demonstrator, відключаємо перехідник, і включаємо мікроконтролер в звичайному режимі(коли при включеннівисновок BOOT 0 з'єднаний з мінусом живлення мікроконтролера). Радіємо!

Отже, тепер ми знаємо, чим мікроконтролери STM кращі за інших, знаємо як працює мікроконтролер, вміємо прошивати мікроконтроллер у налагоджувальній платі та у своїй платі, знаємо основи мови Сі, які потрібні для програмування STM32, отримали досвід роботи з мікроконтролером (сподіваюся позитивний) та саме головне, тепер Ви можете втілити свої ідеї цифрових пристроїву життя (і розповісти про них, на нашому улюбленому РадіоКоті)! Нехай поки що простенькі, але все навюрстується з досвідом. А я постараюся в наступних статтях розповісти про АЦП, ЦАП, переривання, використання налагодження та інші корисності.

Як вам ця стаття?

ST-Link/V2 спеціальний пристрійрозроблене компанією ST для налагодження та програмування мікроконтролерів серії STM8 та STM32. Про сам прилад можна прочитати на сайті компанії ST.

Основні його можливості:

    Вихід 5В для живлення пристрою

    USB 2.0 високошвидкісний інтерфейс

    SWIM, JTAG/serial wire debugging (SWD) інтерфейси

    SWIM підтримка низькошвидкісного та високошвидкісного режимів

    SWD and serial wire viewer (SWV)

    Можливість Оновлення прошивки

Оскільки мікроконтролери STM32 побудовані на ядрі ARM Cortex, яке має інтерфейс налагодження SWD, то ST-Link дозволяє програмувати та налагоджувати й інші 32-бітові мікроконтролери на базі ARM-Cortex.

Це, можна сказати, єдиний програматор мікроконтролерів STM8. Для програмування STM32 є й інші універсальні програматори.

Де можна придбати програматор STM8 STM32 ST-Link

на поточний моментінтерес до мікроконтролерів ST дуже великий. Тому програматор ST link досить поширений над ринком. Існує кілька версій, що відрізняються за ціною.

Оригінальний ST Link від компанії ST, як завжди, найдорожчий варіант. Коштує більше 2000 руб.

Міні ST link (дуже схожий на наш варіант цього програматора) коштує близько 600 руб. Купити його можна у великих постачальників електроніки – Компел, Терра електроніка та інші.

Ali express (Китай) - тут пропонується велика кількість найпростіших варіантів Програматора, але загалом, всі вони робітники, ними вполе можна користуватися. Як правило, вони підходять для програмування STM8 і STM32. Єдине, вони не мають SWO виходу, але він потрібний не так часто. Мабуть, єдиний мінус тут, це очікування покупки. Ціна близько 150-200 руб.

Якщо вам не потрібен програматор STM8, а потрібна лише серія STM32, то хорошим варіантом будуть плати Discovery від ST, вони мають на борі програматор ST link. Однак, як правило, роз'єм для програмування STM8 там не розлучений.

Ну і звичайно, можна просто купити деталі та зробити цей пристрійсамостійно. В основі лежить не найдешевший мікроконтролер STM32, та й купити деталі дешево не так просто, так що вартість буде від 300 до 400 рублів. У цій статті ми розповідатимемо, як зібрати даний прилад самостійно з набору необхідних компонентів SMD. Звичайно ж, ми рекомендуємо піти цим шляхом. Тільки так ви зможете навчитися трасування плат, їх виготовлення та паяння.

Як виготовити програматор ST-LINK V2

2. Підготувати або придбати необхідні інструменти: все для паяння, USB UART адаптер (потрібний для програмування МК)

4. Завантажити необхідні файли з даного приладу з github.

5. Виготовити плату для приладу самостійно (це зовсім нескладно, у нашій інструкції докладно описано).

6. Придбати всі необхідні комплектуючі можна в нашому магазині 300 руб.

7. Запаяти всі компоненти на плату, дивись наше відео.

ПРИЛАД ГОТІВ, можна скористатися!

Пошук схеми для ST Link програматора, відладчика

Сама компанія ST не дає нам схему даного приладу, проте є схеми її ознайомлювальних плат серії DISCOVERY, в яких наводиться схема відладчика. Наприклад, документ UM0919. Але вона не повна, там є тільки SWD інтерфейс. В основі мікроконтролера STM32F103C8T6.


Друга схема, яка є у документі UM1670, містить висновки SWIM виходів, але це вже версія V2.2 на іншому мікроконтролері STM32F103CBT6.


Також в інтернет вдалося знайти схему ST-LINK v2, відновлену за оригінальним приладом:

Ось із цих трьох схем нам треба розробити схему для нашого пристрою. Але спочатку давайте складемо основні вимоги до приладу, який ми робитимемо.

Вимоги до нашого ST-LINK

Ми робитимемо прилади на базі STM8, а також STM32, процесорів NUVOTON Cortex-M0, ATMEL. Всі вони харчуватимуться від 3.3В або 5В. Так що нам не потрібна можливість працювати з мікроконтролерами на напрузі 1.8В. Але сама можливість програмувати STM8 потрібна обов'язково.

Ми робимо прилад для своїх завдань, тому у нас немає потреби у стандартних роз'ємах SWIM та JTAG. Робитиме такий роз'єм, який зручніший для трасування плати.

Версія 2.2 на мікроконтролері STM32F103CBT6 додає друге USB пристрій- COM порт UART, але він уже у нас є, тож, немає сенсу переплачувати, мікроконтролер там дорожчий. Щоправда, у нього є хороша можливість- Прошивка через інтерфейс DFU, тобто мікроконтролер бачиться як флешка при підключенні по USB, і прошивку просто треба скопіювати на диск. Але прошити треба буде один раз, і для цього у нас є USB UART адаптер, прошиватиме перший раз через нього. Подальше оновлення прошивки йде вже через програму від ST USB. Ми робитимемо версію 2.0 на базі STM32F103C8T6.

Оригінальна версія ST-Link містить мікросхему перетворення рівнів, що зручно для налагодження та прошивки готового пристрою, та необхідно для роботи з напругою нижче 3.3В. У нас таких не буде, а для роботи з 5В та 3.3В – перетворення рівнів не потрібно.

Прилад робитимемо у форматі USB dongle, відповідно використовуватимемо роз'єм USB-A male.

На захисті виходів можна заощадити, тому не будемо використовувати захисні діоди. Достатньо буде опорів на всіх виходах роз'ємів на випадок, якщо раптом ми підключимо їх на 5В або землю. Потрібно обов'язково мати на увазі, що користуватися цим приладом треба акуратно! Усі виходи під час підключення перевіряти кілька разів! Вихід 3.3В більше захищений, він іде через регулятор напруги, що захищає від КЗ. Так що краще живити тестові схеми від нього!

Тепер можна скласти фінальну схему ST-Link.

В інтернет запропоновано багато готових плат та схем даного приладу, але з метою навчання ми спеціально будуємо схему та робимо плату самі, ґрунтуючись на DATASHEET, викладених проводником. Якщо ви копіюєте схему з якогось іншого сайту, ви повинні в ній розібратися, що і як там зроблено, чому викинули або додали якісь елементи.

Фінальна схема

Саму схему можна подивитися у файлах даного приладу. Тут же наведемо її для коментування основних вузлів.

Основна частина:


Живлення та роз'єми:

Невеликі коментарі.

Як регулятор живлення на 3.3в використовуємо NCP603 - дуже хороший LDO, видає струм до 300ма з падінням 300mv і точністю +-3%. Індикація світлодіоди - звичайні smd світлодіоди двох кольорів. Для програмування UART необхідно висновок BOOT0 з'єднати з +3В, для цього виведемо його на роз'єм. Також необхідно вивести сам UART – ніжки RX TX. Решту висновків без захисту виведемо на роз'єм. Користуюсь цим програматором уже більше року, і кз були і перешкоди – нічого не згоріло жодного разу.

У деяких схемах ставиться запобіжник, що самозупиняється, на живлення від USB для захисту самого порту. Сучасні комп'ютеримають захист на портах USB, у тому числі запобіжники та струмові обмежуючі ключі, тому він не потрібен. Але краще, звичайно, не перевіряти це, і не помилятися!Напруга 3.3в йде з нашого LDO, який має захист від КЗ та від перегріву, і не видає більше 600ма, там теж захищати нема чого.

Дуже зручно підключати STM8 для програмування за допомогою ST-Link, потрібно всього 3 дроти - живлення, земля та SWIM вихід. Це так само зручно при розведенні плат, можна розводити лише SWIM вихід, землю та харчування завжди можна знайти на платі.

Трасування плати в Kicad за допомогою автотрасувальника Topor

У приладі USB UART адаптер ми вже тренувалися трасувати плату в Kicad вручну. Цей прилад трохи складніше. На ньому можна повчитися розводити плату в автотрасувальники TOPOR. Весь процес краще переглянути на відео наприкінці статті, тут будуть лише невеликі коментарі до відео.

Підготовка плати до автотрасування

Для того щоб працювати з Topor, треба спочатку підготувати плату в Kicad. Необхідно визначити межі плати, імпортувати всі компоненти та попередньо їх розташувати. У нас немає вимог до роз'ємів, тому на першому етапі краще роз'єм видалити з плати. Оскільки кожен висновок роз'єму з'єднаний через резистор, то резистори і будуть орієнтиром висновків роз'єму. Також для розміщення компонентів можна видалити всі конденсатори живлення, кварці, мікросхеми живлення (їх краще розташовувати на зворотній стороні– там зазвичай багато місця) – це все можна розставити потім.

Тепер потрібно визначити сторону кожного копонента. І приблизно розташувати їх як необхідно, роз'єм розташувати біля краю. І на цьому етапі можна все це перекинути до Topor і там продовжити розміщення копонентів. USB роз'єм, світлодіоди відразу розташовуємо на звороті, все інше на лицьовій.

Розміщення компонентів за допомогою Topor

Тепер переносимо це все у Topor та продовжуємо там. Чим гарний Topor? Тим, що кожного разу, подвигнувши компоненти, можна перепрокласти всі траси автоматично і подивитися стало краще чи гірше. Також Topor вміє перевертати прості компоненти – резистори, конденсатори. Нам важливо зрозуміти як зручніше розмістити висновки роз'ємів та основні компоненти.

Покрутивши і подвигнувши компоненти в Topor, ми прийшли до такого розташування:


Тепер необхідно цей результат перекинути Kicad назад і додати інші компоненти. Перед фінальним трасуванням необхідно:

    розмістити мікросхеми живлення

    розвести вручну ланцюги живлення

    розмістити і підключити кварц, і конденсатори живлення

    перевизначити висновки роз'єму на схемі.

Автотрасування

Перекидаємо наше напівтрасування в Topor.

Необхідно відразу встановити правила трасування - ширину проміжків, доріжок, розміри перехідних отворів. При першому імпорті з Kicad треба виділити всі компоненти і зафіксувати їх, щоб можна було легко видалити кнопкою del і знову перепрокласти трасування, залишаючи наш напівручний варіант. У параметрах автотрасування обов'язково необхідно встановити галку «Використовувати наявну розведення як початковий варіант», інакше наші ручні траси будуть перепрокладені (Сам процес роботи в Topor дивись на відео).

Після автотрасування перекидаємо все назад і доводимо до фінального варіанту - додаємо земляні полігони, вирівнюємо де необхідно доріжки. Плата готова.

Фінальний варіант плати

Лицьова сторона


Зворотній бік

Прошивка ST Link, встановлення драйверів

Плата готова, робимо її методом холодного перенесення тонера ацетоном (або будь-яким іншим), труїмо, збираємо прилад. Перед першим включенням обов'язково перевірте будь-яким мультиметром, що між 5В і GND опору немає (нескінченно велике) - це буде гарантувати, що немає короткого замикання. Також треба перевірити опір між 3.3В та GND.

Для роботи з нашим пристроєм необхідно встановити драйвера, прошити його вперше за UART стартовою прошивкою і потім оновити прошивку до останньої версії спеціальною програмоювід ST.

Всі мікроконтролери STM32 мають bootloader і прошиваються UART. Для прошивки необхідно:

Тепер у нас є ST LINK, але зі старим прошивкою. Забираємо всі дроти. Завантажуємо із сайту ST програму оновлення прошивки STSW-LINK007 та драйвера STSW-LINK009 для windows. Вставляємо новий ST-Link в USB порткомп'ютера, і запускаємо програму оновлення прошивки, в ній тиснемо CONNECT і потім оновити прошивку до останньої версії. Прилад готовий! Тепер у вас є програматор-налагоджувач і можна перейти до програмування.

Готовий пристрій

Самостійна робота

Потренуйтеся розводити плату. Зробіть це вручну, за допомогою програми Topor та без. Ви повинні вміти швидко робити будь-яку нескладну плату.

Ця стаття є першою в планованому циклі статей з вивчення програмування мікроконтролерів. Вивчаючи різні матеріали я зазначив, що практично всі вони починаються з того, що новачкові пропонується завантажити (або використовувати бібліотеку, що йде з середовищем розробки) для роботи з периферійними пристроями і використовувати її для написання своєї першої програми (зазвичай миготіння світлодіодом).

Мене це дуже здивувало. Якщо вірити цим статтям, для програмування не обов'язково навіть читати документацію до програмованого контролера. Мене ж навчали премудростям "залізного програмування"зовсім інакше.

У цій статті, шлях від фрази "Так, я хочу спробувати!" до радісного підморгування світлодіода буде значно довше ніж у інших авторів. Я постараюся розкрити аспекти програмування мікроконтролерів, які ховаються за використанням бібліотечних функцій та готових прикладів.
Якщо ви маєте намір серйозно вивчати програмування мікроконтролерів ця стаття для вас. Можливо, вона може зацікавити і тих, хто вдосталь награвся з Arduino і хоче одержати до рук всі апаратні можливості заліза.

Вибір мікроконтролера

Багато хто може сказати, що починати вивчення мікроконтролерів краще з AVR, PIC, 8051 або чогось ще. Питання багатогранне та спірне. Я знаю достатньо прикладів, коли люди, вивчивши Cortex-M, програмували AVR, ARM7 і т.д. Сам же я починав із Cortex-M3. Якщо перед вами стоїть певне завдання, в інтернеті досить багато інформації з порівнянням різних типів мікроконтролерів і задач, що вирішуються з їх допомогою. На хабрі це питання теж порушувалося, наприклад.

Вважатимемо, що з типом мікроконтролера ми розібралися. Але на ринку представлений найбільший діапазон різних модифікацій від різних виробників. Вони відрізняються безліччю параметрів - від розміру флеш пам'яті до кількості аналогових входів. Для кожного завдання вибір варто робити індивідуально. Ніяких загальних рекомендаційтут і бути неспроможна. Зазначу лише, що варто починати вивчення з МК виробників, які мають якомога більший асортимент. Тоді, при виборі МК для конкретного завдання досить великий шанс, що з представленого асортименту вам щось підійде.

Я зупинив свій вибір на STM32(хоча і вважаю, що краще починати вивчення з МК від TexasInstruments - дуже грамотно складено документацію), тому що вони широко поширені серед російських розробників електроніки. При виникненні проблем та питань ви зможете легко знайти рішення на форумах. Ще одним плюсом є багатий вибір демонстраційних плат як від виробника, і від сторонніх організацій.

Що необхідне вивчення?

На жаль, для початку програмування МК мало лише ПК. Прийде десь роздобути демонстраційну плату і програматор. Хоча це зменшує конкуренцію на ринку праці.

Сам я використовую демонстраційну плату STM3220G-EVALта програматор J-Link PRO. Але для початку, буде цілком достатньо STM32F4DISCOVERY, що можна купити без особливих проблем за невелику суму.

Усі приклади будуть саме для налагоджувальної плати STM32F4DISCOVERY. На даному етапі нам буде зовсім не важливо, що ця плата коштує МК на базі ядра Cortex-M4. Найближчим часом ми не будемо використовувати його особливості та переваги над Cortex-M3. А як там буде далі – побачимо.

Якщо у вас є будь-яка інша плата на базі STM32F2xx/STM32F4xx, ви зможете працювати з нею. У викладі матеріалу я намагатимусь максимально докладно описувати чомуми робимо саме так, а чи не інакше. Сподіваюся ні в кого не виникне проблем із перенесенням прикладів на інше залізо.

Середовище розробки

Як уже неодноразово згадувалося, для ARM мікроконтролерівіснує достатньо середовищ розробки, як платних так і не дуже. І знову хочеться опустити полеміку із цього приводу. Я використовую IAR Embedded Workbench for ARM 6.60. Усі приклади будуть саме у цьому середовищі. Якщо вам до вподоби (або у вашій організації використовується) щось інше (Keil, Eclipse, CCS, CooCoc і т.д.), то це вам теж не дуже завадить. На особливості, пов'язані саме з середовищем розробки, я звертатиму окрему увагу.

Чому платне середовище розробки?

Можливо, хтось буде не зовсім задоволений тим, що я пропоную використовувати платне середовище розробки, але IAR має можливість отримати тимчасову ліцензію без обмеження функціоналу або безлімітну ліцензію з обмеженням за розміром коду (32КБ для МК це дуже багато).
Крім цього, відразу зауважу, що для деяких МК немає безкоштовних середовищрозробки. І на жаль ці МК у деяких областях незамінні.


Процес встановлення я описувати не буду.

З чого почати?

Створення проекту
Спочатку створимо порожній проект. IAR дозволяє створити проекти на ASM, C та C++. Ми будемо використовувати C.

Перед нами з'явиться порожній проект із main файлом.

Тепер необхідно налаштувати проект для початку роботи з «нашим» МК та відладчиком. На платі STM32F4DISCOVERY встановлено MK STM32F407VG. Його необхідно вибрати у властивостях проекту (General Options->Target->Device):

При виборі цільового програмованого процесора відбувається завантаження його опису, що дає широкі можливості для налагодження (про це йтиметься нижче). Крім того, автоматично приєднується файл конфігурації з описом доступного адресного простору для лінкера. Якщо буде необхідно, ми торкнемося теми конфігураційного файлулінкера у наступних статтях.

Після цього необхідно налаштувати налагоджувач. Налагодження програми відбувається безпосередньо «в залізі». Виробляється це за допомогою JTAG відладчика. Детальніше ознайомитися з тим, як це відбувається можна на Вікіпедії. На плату STM32F4DISCOVERY вбудований відладчик ST-LINK/V2. Для роботи з налагоджувачем необхідно вибрати його драйвер у меню Debugger->Setup->Driver. Також необхідно вказати, що налагодження має проводитися безпосередньо в залозі. Для цього необхідно поставити прапор Debugger->Download->Use flash loader(s)


Для тих, хто побачив слово Simulator

Теоретично IAR дозволяє налагоджувати програми з використанням симулятора. Але я жодного разу практично не зустрічав його використання.

Тепер проект готовий для роботи (програмування, заливання та налагодження).

ТЗ для першого проекту
Підіб'ємо проміжний підсумок:МК та налагоджувальна плата обрані, проект підготовлений. Час визначитися із завданням.

Не відходитимемо від класики. Першим проектом буде миготливий світлодіод. Благо на платі їх достатньо. Що ж це означає з погляду програмування? Насамперед необхідно вивчити принципову схемудемонстраційної плати та зрозуміти як «заводиться» світлодіод.
доступний на сайті виробника. У даному описінавіть є окремий розділ про світлодіоди на платі - 4.4 LEDs. Наприклад, будемо використовувати User LD3. Знайдемо його на схемі:

Найпростіший аналіз схеми говорить про те, що для того, щоб "запалити" світлодіод необхідно на пін МК подати "1" (яка для даного МК відповідає 3.3В). Вимикання проводиться подачею на цей пін «0». На схемі цей пін позначається PD13(це, мабуть, найважливіша інформація з цього документа).

У результаті ми можемо написати «ТЗ» для нашої першої програми:
Програма для МК повинна переводити стан піна МК PD13 зі стану "0" в стан "1" і назад з деякою періодичністю, помітною для людського ока (важливе зауваження, якщо моргати світлодіодом занадто часто око може цього не розрізнити).

Перш ніж приступати до програмування, або трохи теорії
Перш ніж приступити до реалізації нашого ТЗ, необхідно зрозуміти, як проводиться управління МК.

Почнемо з того, що будь-який МК включає ядро, пам'ять та периферійні блоки. Думаю, що з пам'яттю поки що все зрозуміло. Згадаю лише, в STM32 є флеш пам'ять в якій зберігається програма МК (загалом це не вірне твердження, програма може зберігатися у зовнішній енергонезалежній пам'яті, але поки це опустимо) та інші дані, в тому числі і користувацькі. Також є SRAM - оперативна пам'ять.

Ядро - частина мікроконтролера, що здійснює виконання одного потоку команд. У нашому МК тип ядра – Cortex-M4. Ядро МК можна порівняти з процесором у ПК. Воно вміє лише виконувати команди та передавати дані іншим блокам (у цьому порівнянні не враховуються процесори з інтегрованими графічними прискорювачами).
У цьому виробник МК не розробляє ядро. Ядро купується у компанії ARM Limited. Головна відмінність між різними МК – у периферії.

Периферійні блоки - блоки, що здійснюють взаємодію із «зовнішнім світом» або виконують специфічні функції, недоступні ядру МК. Сучасні МК (зокрема і STM32) містять величезний спектр периферійних блоків. Периферійні блоки призначені для вирішення різних завданьвід зчитування значення напруги з аналогового входу МК до передачі даних зовнішнім пристроям по шині SPI.
На відміну від ядра МК, периферійні блоки не виконують інструкції. Вони лише виконують команди ядра. При цьому участь ядра у виконанні команди не потрібна.

приклад

Як приклад можна навести блок UART, який призначений для прийому та передачі даних від МК зовнішнім пристроям. Від ядра потрібно лише налаштувати блок і віддати йому дані передачі. Після цього ядро ​​може виконувати інструкції. На плечі периферійного блоку лягає керування відповідним висновком МК для передачі даних відповідно до протоколу. Периферійний блок сам переводить вихід МК у необхідний стан «0» або «1» потрібний моментчасу, здійснюючи передачу.

Взаємодія ядра з периферійним блоком
Взаємодія ядра МК з периферійним блоком здійснюється за допомогою спецрегістрів (є ще взаємодія через механізм переривань та DMA, але про це у наступних постах). З погляду ядра це просто ділянка пам'яті з певною адресою, ось тільки насправді це не так. Запис даних у спецреєстр еквівалентна передачі команди або даних периферійному блоку. Зчитування – отримання даних від блоку чи зчитування його стану. Опис периферійних блоків та їх спецрегістрів займає левову частку опису МК.

ВАЖЛИВО:Після запису даних до спецреєстру та наступного читання ви можете отримати зовсім інші дані. Наприклад, передача даних блоку UART для відправки, та зчитування даних, отриманих блоком від зовнішнього пристрою, Здійснюється за допомогою одного і того ж регістру.

Спецреєстри зазвичай поділені на бітові поля. Один (або кілька) біт керують певним параметром периферійного блоку зазвичай незалежно. Наприклад, різні біти одного регістру керують станом різних виходівМК.

Згадуємо З
Якщо ви гуру в мові C, можете сміливо пропускати цей розділ. Він призначений насамперед для тих, кого вчили (чи хтось навчався сам) програмувати для ПК. Досвід свідчить, що часто не пам'ятають важливих команд. Тут я коротко нагадаю про побітові операції та роботу безпосередньо з пам'яттю на її адресу.

Запис даних за адресою у пам'яті

Припустимо, що, читаючи опис периферійного блоку, ми зрозуміли, що для нього коректної роботинеобхідно записати до нього число 0x3B. Адреса спецреєстру 0x60004012. Регістр 32-бітний.
Якщо ви не знаєте як це зробити, спробую описати ланцюжок міркувань для отримання правильної команди.

Значення 0x60004012 не що інше, як значення вказівника на комірку пам'яті. Потрібно саме це і вказати в нашій програмі, тобто зробити перетворення типів згідно з синтаксисом мови C:

(unsigned long*)(0x60004012)

Таким чином, ми маємо вказівник на елемент. Тепер потрібно в цей елемент записати потрібне значення. Робиться це розіменування покажчика. Таким чином отримуємо правильну команду:

*(unsigned long*)(0x60004012) = 0x3B;

Установка довільних біт

Припустимо, що необхідно встановити «1» в 7 і 1 біти за адресою 0x60004012, при цьому не змінивши значення решти всіх біт в регістрі. Для цього необхідно використовувати бінарну операцію | Відразу наведу правильну відповідь:

* (unsigned long *) (0x60004012) | = 0x82;

Зверніть увагу на 2 факти. Біти зважають на нульове, а не на першого. Ця операція насправді займає не менше трьох тактів - зчитування значення, модифікація, запис. Іноді це не допустимо, оскільки між зчитуванням та записом значення одного з бітів, які нам заборонено змінювати, могло бути змінено периферійним блоком. Не забувайте про цю особливість, інакше можуть полізти баги, які дуже важко відловити.

Установка довільних біт 0

Припустимо, що необхідно встановити «0» в 7 і 1 біти за адресою 0x60004012, при цьому не змінивши значення решти всіх біт в регістрі. Для цього необхідно використати бінарну операцію &. Відразу наведу правильну відповідь:

*(unsigned long*)(0x60004012) &= 0xFFFFFF7D;

Або його простіший запис (не переживайте за зайву операцію, компілятор все заздалегідь вважатиме навіть за мінімальної оптимізації):

*(unsigned long*)(0x60004012) &= (~0x82);

Деякі особливості програм для МК
Тут я постараюся описати деякі особливості програм для МК, які важливо пам'ятати. Речі досить очевидні, але все ж таки.
У програми немає кінця
На відміну від більшості програм для ПК, програма для МК не повинна закінчуватися, НІКОЛИ! А що власне має робити МК після завершення вашої програми? Питання практично риторичне. Тому не забуваймо переконатися в тому, що ви не забули вічний цикл. За бажання можна перевести МК в режим сну.
Користуйтесь цілими перемінними
Незважаючи на те, що ми використовуємо МК з ядром Cortex-M4, який апаратно виконує операції над числами з точкою, що плаває, раджу вам відмовитися від їх використання. У МК без підтримки таких операцій час обчислень буде величезним.
Відмовтеся від динамічного виділення пам'яті
Це лише порада. Причина проста – пам'яті мало. Я неодноразово зустрічався з бібліотеками, в яких були «повільні витоки» пам'яті. Було дуже неприємно, коли після кількох тижнів стабільної роботи МК зависав із помилкою. Найкраще продумати архітектуру своєї програми так, щоб не довелося використовувати динамічне виділення пам'яті.
Якщо ж хочеться використовувати - уважно вивчіть роботу менеджера пам'яті або пишіть свій.

Приступаємо до роботи!

Робота над програмою МК завжди починається з читання документації. Для нашого МК доступний на сайті виробника. Сторінок багато, але все читати Бувайне потрібно. Як було зазначено, більшу частину документації становить опис периферійних блоків та його регістрів. Також хочу звернути увагу на те, що цей Reference Manual написаний не для одного МК, а для кількох лінійок. Це говорить про те, що код буде переносимий при переході на інші МК в цих лінійках (якщо звичайно не намагатися використовувати периферійні блоки яких немає в МК, що використовується).

Насамперед необхідно визначитися з якими блоками потрібно працювати. Для цього достатньо вивчить розділи Introductionі Main features.

Безпосереднє керування станом пінів МК здійснюється за допомогою блоку GPIO. Як зазначено в документації МК STM32 може бути до 11 незалежних блоків GPIO. Різні периферійні блоки GPIO називають портами. Порти позначаються літерами від A до K. Кожен порт може містити до 16 пінів. Як зазначили раніше, світлодіод підключається до піна PD13. Це означає, що керування цим піном здійснюється периферійним блоком GPIO порт D. Номер піна 13.

Жодних інших периферійних блоків цього разу нам не знадобиться.

Управління тактуванням периферійних блоків
Для зниження електроспоживання МК практично всі периферійні блоки після включення МК вимкнено. Увімкнення/вимкнення блоку здійснюється подачею/припиненням подачі тактового сигналу на його вхід. Для коректної роботи необхідно конфігурувати контролер тактового сигналу МК, щоб необхідному периферійному блоку надходив тактовий сигнал.
Важливо:Периферійний блок не може розпочати роботу відразупісля увімкнення тактового сигналу. Необхідно почекати кілька тактів, поки він «запуститься». Люди, які використовують бібліотеки для периферійних пристроїв, часто навіть не знають про цю особливість.

За включення тактування периферійних блоків відповідають регістри RCC XXX peripheral clock enable register.На місці XXX можуть стояти шини AHB1, AHB2, AHB3, APB1 та APB2. Після уважного вивчення опису відповідних регістрів, можна дійти невтішного висновку у тому, тактування периферійного блоку GPIOD включається установкою «1» в третій біт регістра RCC AHB1 Peripheral Clock Enable Register (RCC_AHB1ENR):

Тепер необхідно розібратися з тим, як дізнатися адресу самого регістру RCC_AHB1ENR.

Примітка:Опис системи тактування МК STM32 гідно окремої статті. Якщо у читачів виникне бажання, я докладніше висвітлю цей розділ в одній із наступних статей.

Визначення адрес спецрегістрів
Визначення адрес спецрегістрів необхідно починати з читання розділу Memory mapу Reference manual. Можна помітити, що кожному блоку виділено свою ділянку адресного простору. Наприклад, для блоку RCC це ділянка 0x4002 3800 - 0x4002 3BFF:

Для отримання адреси регістра необхідно до початкового значення адресного простору блоку RCC додати Addr. offsetнеобхідного регістру. Address offsetвказується і в описі регістру (див. скріншот вище).

У результаті ми визначили адресу регістру RCC_AHB1ENR- 0x4002 3830.

Блок GPIO
Для загального ознайомлення з блоком GPIO я рекомендую повністю прочитати відповідний розділ Reference Manual. Поки що можна не особливо звертати увагу на Alternate mode. Це залишимо на потім.

Нині ж наше завдання навчитися керувати станом пінів МК. Перейдемо відразу до опису регістрів GPIO.

Режим роботи
В першу чергу необхідно встановити режим роботи 13 піна порту D як General purpose output mode, що означає, що блок GPIO буде керувати станом піна МК. Управління режимом роботи пінів МК здійснюється за допомогою регістру GPIO port mode register (GPIOx_MODER) (x = A..I/J/K):

Як видно з опису для здійснення необхідної нам настройки необхідно записати значення 01b в 26-27 біт регістру GPIOx_MODER. Адресу регістру можна визначити тим же методом, що описаний вище.

Налаштування параметрів роботи вихідних пінів порту GPIO
Блок GPIO дозволяє застосувати додаткові налаштуваннядля вихідних пінів порту. Дані налаштування виконуються в регістрах:
  • GPIO port output type register (GPIOx_OTYPER)- задається тип виходу push-pull або open-drain
  • GPIO port output speed register (GPIOx_OSPEEDR)- задається швидкість роботи виходу
Ми не змінюватимемо даних параметрів, оскільки нас цілком влаштовують значення за замовчуванням.
Встановлення значення на піні МК
Нарешті ми підійшли на момент управління станом виходу МК. Для встановлення вихідного значення на певному піні МК є два методи.

Використовуємо регістр GPIO port bit set/reset register (GPIOx_BSRR)

Запис "0" або "1" у біти 0-16 призводять до відповідної зміни стану пінів порту. Для того, щоб встановити певне значення на виході одного або декількох пінів МК і не змінити решту, необхідно буде користуватися операцією модифікації окремих біт. Така операція виконується не менше ніж за 3 такти. Якщо необхідно в частину бітів записати 1, а інші 0, то знадобиться щонайменше 4 тактів. Даний метод краще використовувати для зміни стану виходу на протилежне, якщо його початковий стан не відомий.

GPIO port bit set/reset register (GPIOx_BSRR)

На відміну від попереднього методу, запис 0 у будь-якій з бітів даного регістру не приведе ні до чого (та й взагалі, всі біти write-only!). Запис 1 в біти 0-15 призведе до встановлення "1" на відповідному виході МК. Запис 1 в біти 16-31 призведе до встановлення "0" на відповідному виході МК. Цей метод кращий за попередній, якщо необхідно встановити певне значення на піні «МК», а не змінити його.

Запалюємо світлодіод!
Знайшовши адреси всіх необхідних регістрів, можна написати програму, яка включає світлодіод:
void main() ( //Enable port D clocking *(unsigned long*)(0x40023830) |= 0x8; //little delay for GPIOD get ready volatile unsigned long i=0; i++; /Set PD13 як General purpose output *(unsigned long*)(0x40020C00) = (*(unsigned long*)(0x40020C00)& (~0x0C000000)) |(0x04000000); (0x40020C14) |= 0x2000; while(1);
Можна компілювати ( Project->Compile) і заливати ( Project->Download->Download active application). Або запустити налагодження ( Project->Dpwnload and Debug) та розпочати виконання (F5).
Світлодіод спалахнув!
Блимаємо світлодіодом
Блимання світлодіода є ні що інше, як поперемінне включення та вимкнення із затримкою між цими діями. Найпростіший спосіб - помістити включення та вимкнення у вічний цикл, а між ними вставити затримку.
void main() ( //Enable port D clocking *(unsigned long*)(0x40023830) |= 0x8; //little delay for GPIOD get ready volatile unsigned long i=0; i++; /Set PD13 як General purpose output *(unsigned long*)(0x40020C00) = (*(unsigned long*)(0x40020C00)& (~0x0C000000)) |( 0x04000000); unsigned long*)(0x40020C14) |= 0x2000;//Delay for(i=0; i<1000000 ;++i); //Turn LED OFF *(unsigned long*)(0x40020C14) &= ~0x2000; //Delay for(i=0; i<1000000 ;++i); } }
Значення 1000000 у затримці підібрано експериментально так, щоб період миготіння світлодіода був помітним оком, але й не був занадто великий.
Оптимізуємо алгоритм
Мінусом обраного підходу миготінням світлодіодом є те, що ядро ​​МК більшу частину часу проводить у порожніх циклах, хоча міг би займатися чимось корисним (у нашому прикладі інших завдань немає, але в майбутньому вони з'являться).

Для того, щоб цього уникнути, зазвичай використовується лічильник циклів, а перемикання стан піна МК відбувається при проходженні програми певної кількості циклів.
void main() ( //Enable port D clocking *(unsigned long*)(0x40023830) |= 0x8; //little delay for GPIOD get ready volatile unsigned long i=0; i++; /Set PD13 як General purpose output *(unsigned long*)(0x40020C00) = (*(unsigned long*)(0x40020C00)& (~0x0C000000)) |(0x04000000); %2000000)) ( //Turn LED ON *(unsigned long*)(0x40020С14) |= 0x2020; ) else if(!(i%1000000)) ( //Turn LED OFF *(unsigned long*)(0x40020С14) = ~0x2000; ) ) )
Але і тут не обійдеться без проблем, зі зміною кількості команд, що виконуються всередині циклу, буде змінюватися період миготіння світлодіодом (або період виконання інших команд у циклі). Але на цьому етапі ми не можемо з цим боротися.

Трохи про налагодження
IAR дозволяє здійснювати налагодження програми безпосередньо у залізі. Все виглядає практично так само, як і налагодження програми для ПК. Є режим покрокового виконання, входу до функції, перегляд значення змінних (У режимі налагодження View->Watch->Watch1/4).

Але крім цього, є можливість перегляду значень регістрів ядра, спецрегістрів периферійних блоків (View->Register) і т.п.
Я рекомендую ознайомитися з можливостями дебаггера під час вивчення програмування МК.

Кілька слів на закінчення

Можливо, багато хто скаже, що ручне прописування адрес у програмі це не правильно, оскільки виробник надає файли з визначеннями регістрів та бітових полів, бібліотеки для роботи з периферією та інші інструменти, що полегшують життя розробнику. Я з цим повністю погоджуюсь, але все одно вважаю, що перші кроки у програмуванні МК необхідно робити перекопуючи документацію до вручну, самостійно визначаючи необхідні регістри та бітові поля. Надалі цим можна користуватися, але вміти потрібно обов'язково.
Наведу лише кілька причин для цього твердження:
  • У бібліотеках від виробника іноді трапляються помилки! Я одного разу мало не зірвав термін проекту через це. Декілька разів перепаював чіп, думаючи, сто пошкодив кристал при пайці (до цього таке траплялося). А проблема полягала в тому, що в бібліотеці було неправильно прописано адресу спецреєстру. Зазвичай таке трапляється з МК або лінійками МК, що тільки вийшли на ринок.
  • Бібліотеки для роботи з периферією деяких виробників не реалізують усіх можливостей периферійних блоків. Особливо цим грішив Luminary Micro, яких у подальшому викупили TI. Доводилося писати ініціалізацію периферії вручну.
  • Багато хто звикає починати програмування МК з вивчення прикладів. Я вважаю, спочатку необхідно визначитися з тим, що дозволяє реалізувати МК. Це можна зрозуміти лише прочитавши документацію. Якщо чогось немає в прикладах, це не означає, що це не підтримує. Останній приклад - апаратна підтримка PTP STM32. У мережі, звичайно, можна щось знайти, але це не входить у стандартний набір від виробника.
  • Драйвери периферійних блоків деяких виробників настільки не оптимізовані, що на перемикання стану піна засобами бібліотеки витрачається до 20 тактів. Це недозволена розкіш для деяких завдань.

Дякую всім, хто прочитав мій пост, вийшло значно більше, ніж я очікував на початку.
Чекаю на ваші коментарі та аргументовану критику. Якщо у тих, хто прочитав, виникне бажання - постараюся продовжити цикл статей. Можливо, у когось є ідеї з приводу тих, які варто було б висвітлити - я був би радий їх почути.