STM32VLDiscovery |
Планував я написати наступний пост про роботу з атмелівським апартним TWI (I2C), але поки доступу до AVR не маю, зате маю STM32VLDiscovery, тому поговоримо поки про ARM-мікроконтролери від STMicroelectronics.
ARM -- архітектура популярна (згідно вікіпедії, найбільш поширені 32-бітні процесори). Детально про неї не писатиму, принаймні не зараз, згадаю лише кілька важливих для подальшого розуміння фактів:
По-перше, фірма-розробник, ARM Holding, процесорів не випускає. Вона розробляє лише архітектуру і систему команд та ліцензує її іншим фірмам. Виробники можуть виготовляти процесори або мікроконтролери (System on Chip), що базуються на ядрі ARM, доповнених різними периферійними компонентами, пам'яттю, сопроцесорами, тощо, або розробляти власні архітектур на базі системи команд та архітектурних рішень ARM. Тому під абревіатурою ARM можуть ховатися зовсім різні процесори! Звичайно, у всіх пристроях сімейства багато спільного, але все рівно завжди варто конкретизувати, про який саме ARM мова.
По-друге, існує багато "версій" ядра ARM, які грубо можна поділити на три групи:
- ARM Cortex-A -- "звичайні" процесори, їх, наприклад, можна зустріти в ноутбуках і планшетах
- ARM Cortex-R -- процесори для систем реального часу
- ARM Cortex-M -- мікроконтролери на базі архітектури ARM
Надалі мова йтиме лише про "мікроконтролерні" варіанти ARM, Cortex-M. Важливо усвідомлювати, що хоча в світі мікроконтролерів вони виділяються великою потужністю, однак все ж це саме мікроконтролери і "звичайним" процесорам ARM серії A вони дуже і дуже поступаються -- це просто пристрої різного класу, як мопед і мікроавтобус. Крім того, так як для мікроконтролерів критичним є розмір програм, "Кортекси" підтримують лише "урізані" системи команд -- thumb (виключно 16-бітні команди) і thumb-2 (як 16-бітні, так і 32-бітні). Досягнуто це урізання та "запаковування" у 16 біт зменшенням кількості дозволених комбінацій операндів, перетворення частини операндів на неявні (з ніжністю згадуємо різноманітні div-и та mul-и x86-х), тощо.
Абревіатури
Перш ніж перейти до основного матеріалу статті, для зовсім початківців, наведу деякі часто вживані абревіатури, які використовуватимуться в подальшому:- ADC -- Analog-to-Digital Converter, Аналогово-цифровий перетворювач (АЦП)
- DAC -- Digital-toAnalog Converter, Ци́фро-ана́логовий перетво́рювач (ЦАП) (Згадався студент, який на екзамені, у відповідь на запитання, для чого потрібен ЦАП, відповів, хихикаючи, що для кози...)
- DMA -- Direct Memory Access, Прямий доступ до пам'яті
- PWM -- Pulse-width modulation, модуля́ція за трива́лістю і́мпульсів (Російською - Широтно-импульсная модуляция, ШИМ)
- RTC -- Real-time clock, годинник реального часу.
Апаратура
Щоб не потонути в "зоології" (багато фірм випускають ARM Cortex-M0/M0+/M1/M3/M4 у різних варіантах, кожен з яких має ряд опціональних "фіч"), розглянемо один конкретний приклад. Фірма STMicroelectronics випускає свої ARM-и під іменем STM32 і для них, за доволі низькими цінами, продає відладочні/тестові плати (evaluation boards). Ось, наприклад, такі, як на фото вище -- STM32VLDISCOVERY. Вони містять контролер, фірмовий програматор для нього та трішки периферії для проби -- світлодіоди, кнопки, LCD-екрани, тощо. Для роботи з ними доступний як вільний (Open Source) так і просто безкоштовний (з тими чи іншими обмеженнями) софт. В певному сенсі, плати ці схожі на славнозвісні Ардуїно, навіть існує порт Arduini IDE для них -- Leaflabs Maple IDE (призначене для Leaflab-івського клона ардуїно, тільки з STM32 процесором, але чудово працює і з "фірмовими" відладочними платами). Іноді, враховуючи помітно більшу потужність, говорять, що оті "Discovery"-плати є перспективними конкурентами Arduino, але як на мене вони служать не стільки конкурентом, скільки приємним доповненням. Мінусом є доволі строгі ліцензійні вимоги -- їх не можна використовувати у приладах "на продаж" чи для промислового використання.
Надалі в основному розглядатимемо згадану STM32VLDISCOVERY. Вона обладнана мікроконтролером STM32F100RB, архітектури ARM Cortex M3. Для повноти викладу, згадаю, що він належить до так-званого "medium-density value line" сімейства, де medium-density вказує на об'єм Flash-пам'яті (між 64 і 128Кб), а value line на частоту (24МГц). Детальніше див. "STM32F10x Standard Peripherals Library supported devices and toolchains". Система команд M3 включає всі команди набору thumb, всі thumb-2, апаратне множення (яке виконується за один такт), апаратне ділення, арифметику з насиченням, реалізовано опціональний bit-banding (адресацію окремих бітів). Детальніше можна почитати тут. Його "досьє":
Надалі в основному розглядатимемо згадану STM32VLDISCOVERY. Вона обладнана мікроконтролером STM32F100RB, архітектури ARM Cortex M3. Для повноти викладу, згадаю, що він належить до так-званого "medium-density value line" сімейства, де medium-density вказує на об'єм Flash-пам'яті (між 64 і 128Кб), а value line на частоту (24МГц). Детальніше див. "STM32F10x Standard Peripherals Library supported devices and toolchains". Система команд M3 включає всі команди набору thumb, всі thumb-2, апаратне множення (яке виконується за один такт), апаратне ділення, арифметику з насиченням, реалізовано опціональний bit-banding (адресацію окремих бітів). Детальніше можна почитати тут. Його "досьє":
- Робоча напруга - 3.3В! (Тобто, логічна одиничка відповідає напрузі +3.3В.) Частина виводів -- 5В tolerant
- Частота: 24МГц
- 128кб флеш-пам'яті (пам'яті програм)
- 8кб оперативної пам'яті
- Характерна для багатьох мікроконтролерів EEPROM-пам'ять відсутня, замість неї може використовуватися пам'ять програм (деталі див., наприклад, тут: "Flash память STM32")
- Багато-багато всілякої периферії: DMA, таймери, ADC, DAC, розрахунок CRC, тощо
- Багато комунікаційних інтерфейсів: I2C, SPI, UART, Consumer electronics control (CEC)
Крім контролера на платі є:
- Програматор ST-Link, який дозволяє завантаження та відладку програм по USB (потрібен кабель із mini-B USB конектором) у контролер плати і може використовуватися незалежно програматором -- для програмування інших мікроконтролерів серії STM! (Переключення здійснюється джампером CN3 на платі, доволі приємний подарунок від фірми)
- Два світлодіоди, зелений та синій, доступні для програмістів (не рахуючи червоних діодів на "програматорській" частині) -- під'єднані до до PC9 і PC8 відповідно (Port C, піни 9 і 8)
- Кнопка, під'єднана до PA0 та кнопка RESET
- Роз'єм, JP1, включивши замість якого амперметр, можна заміряти споживання контролера (якщо джампера немає, живлення на контролер не подається)
- Піни +5В і +3.3В для живлення сторонньої апаратури (але зрозуміло, багато з них брати не можна! -- згорять контролери живлення)
Детальніше про її конструкцію, включаючи схеми, можна почитати тут. Купити можна, наприклад, тут, ціна на момент написання - трішки менше 140 грн. (Відгук про той магазин див. тут, за словом "Космодром". З того часу робив ще одне замовлення, знову жодних нарікань чи вартих уваги зауважень. Так що рекомендую.)
"Додаткова література":
"Додаткова література":
- "Знакомство с ARM Cortex-M3 и с STM32, в частности" (від Robocraft)
- "STM32: Урок 3 - Документация" (від Robocraft)
- "Знакомство с STM32VL Discovery" (від EasySTM32)
Апаратні засоби та їх програмування
"Біблією" будь-якого апаратного засобу є його Datasheet (специфікації) та, якщо існує, Reference Manual. Для STM32F100x їх декілька -- по перше, це "мануал" на ядро, ARMv7-M від ARM Holdings, по-друге довідник від STMicroelectronics, "STM32F100xx advanced ARM-based 32-bit MCUs" і даташіт по особливостях STM32F100. (В мережі можна знайти любительський переклад російською).Так як читати даташіти справа нудна, ознайомитися із архітектурою і принципами роботи можна за допомогою "Insider's Guide STM32" від Hitex. Існує його переклад російською.
Взагалі, про те, як працювати із STM32 та платами серії DISCOVERY, як і про Ардуїно, не писав хіба лінивий, тому нижче обмежуся лише коротким оглядом із багатьма посиланнями. Для тих, кому стане нудно читати послідовно -- можна почати з розділу "Перша програма", а тоді повернутися сюди.
CMSIS i SPL (Standard Peripherals Library)
Ці дві абревіатури дуже важливі ;-)CMSIS -- стандартна бібліотека для всіх Cortex-ів, основа її розроблена ARM Holdings, допилюється виробниками мікроконтролерів під їх периферію. Зокрема, у ній визначено всі регістри (тому немає потреби вручну задавати їх адреси в пам'яті -- див. наступний розділ), різноманітні константи, бітмаски і т.д. Популярний огляд CMSIS див. у Ді Халта: "ARM. Учебный Курс. Keil + CMSIS. Создание проекта".
Standard Peropherals Library -- бібліотека від STMicroelectronics для їхніх STM32. Енкапсулює роботу з окремими регістрами, замість безпосереднього звертання до них, спеціальні структури заповнюються потрібними значеннями і передаються функціям, що виконують всю роботу. Звучить мутно, але коли дійде справа до прикладів, стане зрозуміліше :-). Див. опис у вікі, статтю від Ді Халта: "Работа с STM32F10x Standard Peripherals Library", та офіційну документацію. Знайти її можна, наприклад, у архіві з бібліотекою. Там же є багато-багато прикладів використання. Неофіційна онлайн версія тут.
Обидві бібліотеки постачаються у вигляді джерельних кодів (sources), так як багато простіше їх скомпілювати під конкретний контролер, ніж тримати цілий зоопарк можливих скомпільованих варіантів. Взагалі, у світі мікроконтролерів це -- загальна практика. Часто, для зручності, файли бібліотек копіюються в папку проекту. Деякі IDE, зокрема CooCox coIDE, про яку мова нижче, навіть автоматизують цей процес. Скачати офіційну копію бібліотеки для нашої плати можна тут, (посилання з її сторінки), але багато які IDE містять її в комплекті.
Взагалі, якщо десь є приклад коду такого виду:
RCC->APB2ENR |= RCC_APB2Periph_GPIOC;
маємо використання лише CMSIS, а якщо такого:
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);
то SPL. Ді Халт рекомендує завжди починати працювати, обмежуючись CMSIS, і лише розібравшись, для спрощення життя, починати використовувати SPL. Абсолютно з ним згоден в цьому! Хоча, сам іноді роблю навпаки, лінь -- страшна сила...
Карта пам'яті
Почнемо з карти пам'яті -- якщо без знання системи команд можна все рівно доволі впевнено програмувати на C/C++, розуміти що і як адресується, все ж варто в будь-якому випадку.(с) Hitex, "Insider's Guide STM32" |
Далі слідує 0.5Гб для оперативної пам'яті (SRAM). Так як її взагалі лічені кілобайти/десятки кілобайт, місця більш ніж достатньо, тому частину його виділено під bit-banding. Кожне слово із адресою між 0x22000000 і 0x23FFFFFF відповідає одному біту першого мегабайта діапазону від 0x20000000 до 0x20100000. Тобто, встановлюючи слово (нагадуємо, 32-бітне), з області bit-banding, в 1 чи 0, ми встановлюємо чи очищаємо відповідний біт із першого мегабайта. (Знайти адресу відповідного слова просто, хай це буде домашнім завданням, або, якщо зовсім лінь -- див. згадуваний вище "Insider's Guide STM32", в моєму виданні -- сторінка 22). Процесор вміє виконувати код, який знаходиться в оперативній пам'яті (SRAM), але відбуватися це буде повільніше, ніж для коду з Flash.
Наступних 0.5Гб виділено під регістри периферії, вставленої виробником в мікроконтролер. Перший мегабайт так само доступний побітно, (як і SRAM).
Фактично зі всією оперативною пам'яттю і всіма регістрами периферії можна працювати побітно -- вони займають явно менше місця, ніж 1Мб.
Наступні 2Гб виділено, один для зовнішньої пам'яті та один для зовнішніх пристроїв.
Нарешті, останніх 0.5Гб використовуються периферією ядра Cortex-M3. Адреси всіх регістрів ядра співпадають для всіх процесорів сімейства Cortex.
Переривання
Cortex-и мають дуже розвинуту систему переривань, якою завідує NVIC -- Nested Vector Interrupt Controller. Описувати тут її не буду, хоча це і важливо. За деталями -- див.:- Відповідний розділ вже згаданого "Insider's Guide STM32"
- "ARM. Учебный Курс. Прерывания и NVIC — приоритетный контроллер прерываний" (від Easyelectronics та Di Halta)
- "Прерывания в STM32" (від EasySTM32) -- найбільш просте, але як результат - із багатьма спрощеннями та впущеними суттєвими деталями
Что нужно знать о прерываниях:
- Они все независимо включаются/выключаются
- Имеют приоритет
- Могут быть вызваны программно
- Если для прерывания нет обработчика, а оно возникло, то будет вызван обработчик по умолчанию
Шини і тактові генератори
Різноманітних шин у контролера багато, а система тактування складна і розгорнута. Зроблено все це для досягнення більшої ефективності, як у швидкодії, так і у енергоспоживанні. Однак, в результаті, колупатися у тому всьому доволі складно.(с) RM0041 Reference manual: STM32F100xx advanced ARM-based 32-bit MCUs. |
Перший же сюрприз, який чекає на початківця -- після ввімкнення контролера більшість периферії відключена від тактового генератора. Хочете хоча б "посмикати" ніжки -- затактуйте спочатку відповідний порт. Хочете скористатися таймером? Аналогічно. Ну, ви зрозуміли :-) Навіть буфер предвиборки Flash доводиться вмикати окремо (це своєрідний "кеш програм", без нього швидкодія помітно паде).
Всі шини об'єднано у так-звану матрицю шин:
- ICode -- шина, якою контролер завантажує код з Flash
- DCode -- завантаження даних із Flash та інтерфейс відлагодження
- System -- з'єднує системну шину ядра з матрицею шин, здійснює арбітраж доступу між ядром і DMA
- DMA -- з'єднує шину DMA, AHB, з матрицею
Тактування блоків теж реалізовано "складно і багатогранно":
Тактування блоків контролера, (с) Hitex, "Insider's Guide STM32" |
Далі частота "потрапляє" на PLL -- Phase Locked Loop, який, фактично, є помножувачем однієї із частот: HSI/2, HSE, HSE/2, на коефіцієнт від 2 до 16. Керування ним - див. додаткову літературу. Лише слід пам'ятати -- змінювати його налаштування можна тільки поки він вимкнений, після ввімкнення потрібен певний час для виходу на робочий режим (вийшовши, виставляє спеціальний біт, вміє генерувати переривання).
На виході PLL маємо системну частоту, SYSCLK, від якої тактуються всі решта елементи контролера. Кожен із них має свій подільник -- див. схему вище, завдяки чому можна гнучко підбирати частоту роботи всіх блоків.
Додаткова література:
- Само собою, "Insider's Guide STM32"
- "STM32: Урок 5 - Архитектура" (від Robocraft)
- "ARM. Учебный курс. Тактовый генератор STM32" (від від Easyelectronics)
- "ARM Cortex ICode, DCode, System buses" на форму розробників архітектури ARM.
- "STM32L. Система формирования тактовых частот Reset and Clock Control (RCC)" та "STM32L. Пространство памяти и архитектура шин" (від ChipSpace). Увага, інформація стосується близької, але все ж окремої, серії STM32L. Можуть бути дрібні відмінності.
Semihosting
ARM-и мають цікаву "фішку", semihosting -- можливість використовувати у коді майже-звичайні функції сімейства printf, вивід яких можна бачити у консолі відладчика. Іноді дуже зручно! Працює воно за допомогою інтерфейсу із звучною назвою Angel.Кілька слів про деталі можна прочитати тут: "LPCXpresso Урок 6. Semihosting. Использование printf в отладке". Цінна додаткова інформація є в цій статті: "QEMU ARM semihosting". Ну і куди ж без офіційної документації: "ARM Software Development Toolkit User Guide: Angel".
GPIO -- порти вводу-виводу
Менш-більш звичні, але без них нікуди :-). Імена портів -- GPIOx, де x -- A, B, C, D, E, F або G. (STM32F100 на нашій платі має лише A, B, C -- він у корпусі LQFP-64). Кожен порт об'єднує 16 ніжок -- пінів. Мають на диво багато режимів:- Вхід Hi-Z, високоомний
- Вхід з підтяжкою вверх
- Вхід з підтяжкою вниз
- Аналоговий вхід (для ADC)
- Вихід з відкритим колектором (див. опис на вікі та частину статті "STM32: Урок 4 - GPIO" про Open-drain)
- Вихід push-pull
- Альтернативна функція -- push-pull
- Альтернативна функція -- open-drain
В загальних рисах, які альтернативні функції де живуть, можна побачити на рисунку нижче, а детально, із відповідністю пінів контролера пінам плати, описано в таблиці "Extension Connections" даташіта STM32VLDISCOVERY.
Виробник розповсюджує також корисну програмку для візуального конфігурування пінів -- MicroXplorer.
Сенсу переписувати написане багато ким про роботу з GPIO немає, тому просто даю посилання. Не забуваємо, що нульовим пунктом у всіх таких списках стоять даташіти.
- Коротка шпаргалка по портах вводу-виводу -- імена, призначення та формат регістрів: "STM32 GPIO. Описание регистров".
- Шпаргалка по роботі з GPIO засобами SPL: "STM32 GPIO. Использование StdPeriph_Lib"
- "ARM. Учебный Курс. Порты GPIO", (від Ді Халта) -- детально описано можливості та засоби керування
- "STM32: Урок 4 - GPIO", (від Robocraft). Дещо популярніший, ніж вище, виклад. Описано роботу з 5V Tolerant виводами в режимі Open Drain
- Ще одна ґрунтовна стаття: "Порты микроконтроллера", (від EasySTM32)
- Зручна робота з портами за допомогою шаблонів C++: "STM32 GPIOs and Template Metaprogramming"
Таймери
Таймерів у пристрою, який розглядаємо, багато, і вони круті. Їх можна поділити на наступні класи:- SysTick timer -- простий 24-бітний таймер, який є частиною ядра Cortex
- Базові таймери (basic timers), TIM6 і TIM7 для STM32F100
- Таймери загального використання (General-purpose timers) -- TIM2, TIM3, TIM4, TIM15, TIM16, TIM17, які, в залежності від набору можливостей, діляться на групи -- див таблицю нижче.
- Advanced-control timer лише один, TIM1. Він один вміє все, що вміють таймери загального використання.
Перш ніж перейти до розгляду конкретних таймерів, подивимося на матрицю можливостей TIMx:
(c) "STM32F100x4 STM32F100x6 STM32F100x8 STM32F100xB" Datasheet |
SysTick timer
24-бітний лічильник,який зменшується ("декрементивний") та вміє автоперезавантажуватися (що це значить -- трішки нижче). Може тактуватися або системною тактовою частотою SYSCLK, або 1/8 від неї, SYSCLK/8. Регістри для роботи з цим таймером наступні:- SysTick Current Value Register, VAL -- поточне значення лічильника. Коли досягає нуля, генерується переривання.
- SysTick Reload Value Register, LOAD -- значення, яке завантажуватиметься в Current Value Register після того, як він занулився (ось і автоперезавантаження).
- SysTick Control and Status Register, CTRL -- регістр керування та статусу. Використовуються наступні біти: COUNTFLAG (16) -- 1, якщо лічильник досягав нуля з того часу, як його останній раз читали, очищається в нуль, коли його читають або коли очищається лічильник VAL; CLKSOURCE (2) -- зовнішнє (0) або внутрішнє (1) джерело тактового сигналу. TICKINT (1) -- якщо 1, дозволено генерацію переривання, ENABLE (0) -- якщо 1, таймер "дозволено" і він відраховує "тіки".
- SysTick Calibration Value Register, CALIB -- регістр калібрування, може використовуватися, щоб добитися однакових інтервалів між перериваннями, згенерованими SysTick на різних мікроконтролерах сімейства.
typedef struct
{
__IO uint32_t CTRL;
/*!< Offset: 0x00 SysTick Control and Status Register */
__IO uint32_t LOAD;
/*!< Offset: 0x04 SysTick Reload Value Register */
__IO uint32_t VAL;
/*!< Offset: 0x08 SysTick Current Value Register */
__I uint32_t CALIB;
/*!< Offset: 0x0C SysTick Calibration Register */
} SysTick_Type;
#define SCS_BASE (0xE000E000)
/*!< System Control Space Base Address */
#define SysTick_BASE (CS_BASE + 0x0010)
/*!< SysTick Base Address
#define SysTick ((SysTick_Type *) SysTick_BASE)
/*!< SysTick configuration struct */
Цей таймер -- хороший приклад того, як організована CMSIS. Регістри таймера відображаються один за одним у пам'ять, за базовою адресою, яка розраховується як сума базової адреси системної області (див. вище карту пам'яті) та зміщення у ній області регістрів SysTick.
Крім того, для зручності, CMSIS надає функцію SysTick_Config(uint32_t ticks), яка ініціалізує таймер, задає частоту генерації переривань (знаючи системну частоту, можна її привести, хоча і не дуже точно, до одиниць реального часу) та запускає відлік:
static __INLINE uint32_t SysTick_Config(uint32_t ticks)
{
if (ticks > SysTick_LOAD_RELOAD_Msk) return (1);
/* Перевіряємо, чи значення не завелике -- таймер 24-бітний
* SysTick_LOAD_RELOAD_Msk -- 24 двійкові одинички */
SysTick->LOAD = (ticks & SysTick_LOAD_RELOAD_Msk) - 1;
/* Ініціалізуємо регістр перезавантаження */
NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1);
/* Встановлюємо пріоритет переривання, засобами NVIC */
SysTick->VAL = 0;
/* Задаємо початкове значення лічильника */
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
SysTick_CTRL_TICKINT_Msk |
SysTick_CTRL_ENABLE_Msk;
/* Дозволяємо переривання та запускаємо таймер */
return (0);
}
Зрозуміло, що для досягнення бажаної затримки (в секундах), слід встановити:
ticks = системна частота (в герцах) * час (в секундах)
Тільки не забуваємо, що таймер лише 24-бітний, тому, наприклад, для STM32VLDISCOVERY, з частотою 24МГц, більше 0.7 секунди (8*0.7, якщо тактувати на 1/8 частоти) відрахувати він не зможе. Це обмеження легко обійти програмно -- використати свій лічильник, який змінюватиметься в процедурі обробки переривання.
Головне призначення таймера -- побудова диспетчера операційної системи, але іноді зручно мати аж 24-бітний таймер.
Сподіваюся, мені пробачать такий, непропорційно великий щодо решти компонент мікроконтролера, опис цього таймера, але він -- чи не найпростіший периферійний пристрій, і можна зручно проілюструвати загальні принципи роботи, не тонучи в багатьох бітах десятків регістрів.
Детальніше, традиційно, див. літературу:
- Опис роботи з SysTimer, містить приклади: "STM32. Системный таймер SysTick."
- Опис таймера -- розділ "The SYSTICK Timer" глави 8 "The NVIC and Interrupt Control" у "The Defi nitive Guide to the ARM Cortex-M3" від Joseph Yiu. (Можна знайти на просторах Інтернету, або пишіть мені)
Базові таймери (basic timers)
Їх два, TIM6 і TIM7 (в STM32F100), з наступними можливостями:- 16-бітний лічильник з автоперезавантаженням,
- 16-бітний подільник частоти, (на нього ділиться частота, з якою затактовано таймер, див. відповідний розділ вище)
- 16-бітний регістр періоду, (що задає величину, за якої лічильник перевантажиться),
- схеми синхронізації DAC,
- генерація переривань,
- генерація запитів DMA.
Детальніше див:
- "STM32: Урок 6.1 - Базовые таймеры" (від Robocraft)
- "STM32L. Базовые таймеры TIM6 и TIM7" (від ChipSpace) Увага: знову мова про серію STM32L, можуть бути дрібні відмінності від наших STM32F.
- "Basic таймеры в STM32" (від EasySTM32)
- "Шпаргалки" по темі: "STM32 TIMER basic. Введение и описание регистров", "STM32 TIMER basic. Инициализация и использование".
"Просунуті" таймери -- загального використання і Advanced-control
Ну, це взагалі не таймери, а монстри. Вони вміють (загального використання -- у різних комбінаціях, див. таблицю вище, advanced-contorol -- все зразу) наступне:- Все те, що і базові таймери -- 16-бітні лічильник, 16-бітний подільник частоти, 16-бітний регістр автоперезавантаження, генерація переривань та запитів DMA
- TIM2/3/4 вміють рахувати вверх та вниз
- До 4 каналів захоплення/порівняння сигналів, які можуть служити для: захоплення сигналу, (зокрема захоплення PWM), порівняння виводу, генерація PWM.
- Захоплення сигналу -- із вказаного каналу захоплюються імпульси і поточне значення таймера зберігається в регістрі TIM_CCRx. Можна налаштувати генерацію переривань чи запит DMA на прихід імпульсу, можна ловити фронт, спад сигналу чи і те і те, можна генерувати переривання over-capture, якщо з часу попереднього імпульсу регістр TIM_CCRx не було прочитано, можна налаштувати фільтр, який вказує, після котрої зміни сигналу, (від 0 до 15), слід вважати, що він таки прийшов (зручно для боротьби із дрижанням); можна налаштовувати подільник частоти, ловлячи кожен 2/4/8 сигнал. Захоплення PWM -- хитрий режим захоплення, коли один канал ловить фронти і скидує лічильник, інший -- ловить спади, таким чином фіксуючи, відповідно, період і заповнення сигналу (duty cycle).
- Порівняння виводу по досягненню вказаного значення лічильника, переключає пін у 0, 1, або змінює поточне значення на протилежне.
- Генерація PWM!
- Виділений режим читання енкодера та роботи із датчиками Холла.
- Лічильник повторів -- генерація переривання не кожного переповнення, а лише раз на вказану кількість (від 0 до 255).
- Комплементарні виводи (такі, що мають протилежні логічні рівні), із можливістю програмування dead-time -- затримки між переключенням їх рівнів,
- Синхронізація -- таймери можна об'єднувати, як для синхронізації, щоб одна і та ж подія синхронно запускала кілька таймерів, так і в ланцюжки, коли переривання по переповненню одного таймера генерує одну "лічильну" подію іншого.
- Вхід BRK для зупинки таймера, чи переведення його у заданий стан.
- Фіксація параметрів таймера, без можливості їх зміни до перевантаження контролера.
- RM0041 Reference manual: STM32F100xx advanced ARM-based 32-bit MCUs.
- "STM32F100x4 STM32F100x6 STM32F100x8 STM32F100xB" Datasheet
- "STM32: Урок 6.2 - Таймеры общего назначения и продвинутые", (від Robocraft), з детальними прикладами)
- "Генерация ШИМ в STM32", (від EasySTM32)
- Рубрика "TIMER" від автора "шаргалок", MyController, розділ "STM32 TIMER general-purpose": "Введение", "Описание регистров", "Описание базового молуля", "Система тактирования", "Внешняя синхронизация", "Генерирование события обновления UEV", "Режим захвата", "Режим сравнения" (там же про PWM) і "Функция задержки" -- проста реалізація delay для STM32.
- "STM32 – Подключаем энкодер", (від спільноти Easyelectronics)
Додатково можна подивитися загальні статті: "AVR. Учебный курс. Использование ШИМ (PWM)" від Ді Халта, на прикладі AVR та "ШИМ - Широтно-Импульсная Модуляция" від Robocraft.
ADC
Без Аналогово-Цифрового перетворювача, (АЦП, він же ADC) у аналоговому світі складно. Тому і STM32 ним обладнані. Детально я з ними поки не розбирався, тому обмежуся лише посиланнями:- Вже згадані не раз даташіти на сімейство
- "Insider's Guide STM32", Hitex
- "АЦП в STM32. Часть 1" і "АЦП в STM32. Часть 2" (від EasySTM32)
- Рубрика "ADC" на MyController: "Описание регистров", "Введение", "Описание работы модуля", "Примеры использования. Шаг 1", "Примеры использования: инжектированные каналы".
- Серія статей про ADC для STM32L (не F!): "STM32L. ADC — Аналого-цифровой преобразователь", "STM32L. Регистры АЦП".
DAC
Зворотній до ADC пристрій. Як ерзац-DAC можна використовувати PWM, особливо із конденсатором великої ємності для згладжування, але виділений пристрій все ж зручніше. Крім того, DAC від STM32 вміє генерувати сигнал трикутної форми та шум.- "ЦАП в STM32", (від EasySTM32)
- Рубрика DAC на MyController: "Описание модуля", "Описание регистров", "Примеры использования"
- Серія статей про DAC для STM32L (не F!): "STM32L. DAC — цифро-аналоговый преобразователь. Часть 1", "Часть 2"
I2C
Про шину I2C я вже писав, і ще до цієї теми повернуся не раз, тому теж тільки список посилань:- "STM32L-Интерфейс I2C (кратенько)", (від спільноти Easyelectronics)
- "STM32 I2C EEPROM 24СXX", (від спільноти Easyelectronics)
SPI
Serial Peripheral Interface Bus -- SPI, ще одна популярна послідовна шина. Синхронна, повнодуплексна, шустріша від I2C, зате допускає лише один пристрій на шині (якщо не рахувати chip select -- можливість ввімкнути один конкретний пристрій із декількох присутніх на шині, вимкнувши всі інші). Крім даташітів (а краще -- перед ними :) можна глянути сюди:- Рубрика SPI на MyController: "Введение", "Описание регистров", "Инициализация и работа", "Использование прерываний"
- Статті від ChipSpace: "Интерфейс SPI", "Стандартные библиотеки для модуля SPI" (мова про SPL)
USART
Куди ж без нього, хоча дідусю вже багато-багато рочків:- "UART в STM32. Часть 0", "Часть 1", "Часть 2", (від EasySTM32).
- Рубрика USART на MyController: "Введение", "Назначение регистров", "Инициализация модуля", "Работа с прерываниями", "Использование DMA", "Использование StdPeriph_Lib".
- Серія статей про USART від ChipSpace : "USART. Часть 1", "Часть 2", "Часть 3", "Часть 4".
DMA
Зручна річ: сказав контролеру звідки брати, куди класти, і забув -- периферія із пам'яттю самі розберуться. Думаю, колись розгляну його детально. А поки декілька посилань для затравки:- Рубрика DMA на MyController: "Введение", "Описание регистров", "Инициализация".
- "STM32L. Контроллер DMA"(від ChipSpace). Увага: мова про серію STM32L, можуть бути дрібні відмінності від STM32F.
Список джерел інформації
Для зручності, наведу сайти, на сторінки яких посилаюся вище, та деякі додаткові джерела в одному місці:
- Сторінка плати STM32VLDiscovery, "STM32VLDISCOVERY User Manual" (UM0919), документація "STM32VLDISCOVERY firmware package (AN3268 Application note)" та власне файли бібліотеки.
- Даташіт про особливості контролерів STM32F100x4, STM32F100x6, STM32F100x8, STM32F100xB
- Даташіт на ядро ARMv7-M від ARM Holdings (той же SysTick Timer описаний детально саме там).
- Reference Manual на сімейство: "STM32F100xx advanced ARM-based 32-bit MCUs"
- Так-звані Application Notes ("аппноти") -- приклади роботи із окремими компонентами мікроконтролера. Взяти можна тут, на вкладці "Design support".
- Дуже хороший огляд STM32 сімейства Cortex-M3: "Insider's Guide STM32" від Hitex. Існує його переклад російською.
- Сайт Ді Халта easyelectronics.ru, та його спільноти користувачів, we.easyelectronics.ru. Шукати за словами/тегами "STM32", "ARM", "Cortex".
- Сайт robocraft.ru.
- Сайт mycontroller.ru. Лаконічний та зручний виклад -- своєрідні шпаргалки.
- Сайт chipspace.ru.
- Сайт ziblog.ru.
- Тематичний форум на сайті STMicroelectronics.
- Багато-багато інших.
Програмне забезпечення
Щоб скористатися контролером, крім власне нього, із необхідним "обвісом", слід мати ще різноманітні засоби розробки. Коротко пройдемося по них, (з надією повернутися до деяких в майбутніх постах).Компілятори та IDE
Як не дивно, документація на STM32VLDiscovery рекомендує лише три комерційних пакети:- Keil MDK-ARM, і ARM Development Studio 5. Враховуючи, що ARM купила Keil, наводжу разом. Keil постачає свою IDE та свій компілятор, існує безкоштовна версія пакету, Lite, із обмеженням на величину коду в 32Кб. ARM DS базується на Eclipse, може працювати як зі своїм компілятором, так і з gcc. Обоє містять відладник, симулятор, і ряд корисних бібліотек та інструментів. Не працював із ними, тому детальніше сказати не можу.
- Embedded Workbench for ARM (EWARM) від IAR Systems. Власний компілятор, і якщо не плутаю, власне IDE. Існує безкоштовна версія із обмеженням 32Кб.
- Atollic TrueSTUDIO for ARM. Базується на Eclipse і включає gcc. Існує безкоштовна версія, із тим же обмеженням в 32Кб (8Кб для Cortex-M0 і M1).
Однак, як зрозуміло із написаного вище, для ARM/ARM Cortex існує підтримка в gcc, який, у свою чергу, дружить із Eclipse, тому можна сподіватися на існування відкритих, Open Source, засобів. Сподівання аж ніяк не марні:
- "GNU Tools for ARM Embedded Processors" -- компілятор gcc. Зокрема, скомпільовані для Windows версії.
- Маючи трішки часу, досвіду та бажання попрацювати, гарне середовище можна зібрати самостійно, все із тих же інгредієнтів -- arm-gcc та Eclipse. Як це зробити, описано в статті "STM32: Урок 1 - Настраиваем IDE" від Robocraft.
- Дуже хороша, особливо для початківців, оболонка CoIDE від CooCox. Недоліком є відсутність нормальної підтримки C++, відсутність версії під Linux та глибоке-глибоке закопування можливостей налаштування (якими славиться Eclipse), що іноді сильно ускладнює життя (наприклад, повернення тієї ж підтримки C++ :). Китайська розробка.
- CoIDE: друга частина "STM32: Урок 1 - Настраиваем IDE" присв'ячена, власне, роботі з цим IDE; "Необходимый софт" від EasySTM32.
- Keil: "ARM. Учебный Курс. Keil + CMSIS. Создание проекта" (від Ді Халта); "Встроенный ST-LINK + STM32F103 + Keil" (від ChipSpace).
- IAR EWARM: "ARM. Учебный курс. IAR EWARM. Создание проекта часть 2. CMSIS и Standard Peripherals Library" (від Ді Халта); "STM32. Создание проекта в IAR EWARM. Работа с портами ввода/вывода. Часть 1.", "Часть 2", "Подключение CMSIS в IAR EWARM с версии 6.2" (від ChipSpace).
Також, слід пам'ятати, що типовий у світі мікроконтролерів спосіб підключити бібліотеки -- скопіювати їх у папку проекту, і компілювати разом із власним кодом. Це простіше, ніж тягнути із середовищем безліч комбінацій скомпільованих бібліотек, а сумарний їх розмір і так невеликий, через обмежену пам'ять контролера. Одні оболонки такий процес автоматизують (як вже згадана CoIDE), інші ні (і тоді в інструкціях пише щось типу "скопіюйте cmsis.c i cmsis.h у папку вашого проекту").
Допоміжні засоби
Крім компілятора, оболонки та засобів для прошивки і відлагодження (вони явно не згадувалися, але малися на увазі в попередньому розділі), існує ряд корисних програм, які сильно полегшують життя розробнику. Назву декілька із них:- STM Studio run-time variables monitoring and visualization tool, від STMicroelectronics. Інструмент, за допомогою якого можна слідкувати за змінними у мікроконтролері під час його (менш-більш звичайної) роботи. Працює з використанням стандартних засобів відлагоження, типу ST-Link. Безкоштовна. Стаття про роботу із нею: "STM Studio", від EasySTM32.
- MicroXplorer, MCU graphical configuration tool, від STMicroelectronics. Засіб конфігурування (та підбору оптимальних комбінацій) пінів мікроконтролерів, в залежності від моделі та периферії, із якою планується працювати. Враховуючи громіздкість та "рясність" периферії та велику кількість ніжок контролерів, дуже корисна річ! Дві статті по роботі із ним, хоча програма достатньо інтуїтивна: "Работа с MicroXplorer", від EasySTM32, "STM32. MicroXplorer", від ChipSpace.
- CooCox CoSmart -- за ідеологіє (та й за виглядом), сильно нагадує MicroXplorer, однак ніби надає більше можливостей. На жаль, випробувати поки не вдалося -- підтримки STM32 ще немає, обіцяли на серпень, так що чекаємо.
- CooCox CoAssistant -- інтерактивний довідник по регістрам. Можна користуватися он-лайн!
Операційні системи
Як не дивно, навіть на таких крихітках, як мікроконтролери, є ніша для операційних систем. Детальніше про деякі з них в майбутніх постах, а поки короткий список сумісних із STM32:- ChibiOS/RT. Портабельна, компактна, багатозадачна OS реального часу. Підтримує ряд сімейств мікроконтролерів з архітектурами ARM7/ARM Cortex-Mx/STM8/MSP430/AVR та інші (див. "Supported Architectures"). Підтримує багатозадачність із витісненням, засоби роботи з багатопоточністю, статична по природі (що важливо для мікроконтролерів), але може працювати і динамічно виділяючи ресурси, Hardware Abstraction Layer (HAL) для великого набору периферії (див., правда, Features Matrix, але все рівно, для STM32F1xx підтримується найбільший набір периферії). Open Source -- GPL, GPL with Linking Exception. Є можливість покупки комерційної ліцензії.
- CooCox CoOS. Крихітна, (мінімальне ядро - 974 байт), багатозадачна OS реального часу для ARM Cortex M. Підтримує багатозадачність із витісненням, засоби роботи з багатопоточністю, вміє розпізнавати переповнення стеку. Open Source -- BSD. Розробляється китайцями :-)
- Free RTOS. Дуже популярна і відома. Портабельна, підтримує три десятки архітектур, багатозадачна OS реального часу. Підтримує як кооперативну багатозадачність, так і багатозадачність із витісненням, а також гібридні варіанти. Засоби для роботи з багатозадачністю, програмні таймери, розпізнавання переповнення стеку. Ліцензія -- GPL with Linking Exception, але включає "апаратуро-специфічні" файли із своїми ліцензіями. Існує декілька модифікацій -- OpenRTOS для комерційного використання, та SafeRTOS, підвищеної надійності.
- "Operating Systems and Middleware" від STMicroelectronics
- "Open source Real time Operating Systems for the STM32 and Cortex m3 MCu's"
- "List of real-time operating systems" на Wiki
Інше
Їх забагато, щоб тут перераховувати, але на просторах Інтернету можна знайти дуже багато корисних бібліотек (різної якості та з різними ліцензіями, звичайно) для ARM Cortex взагалі, і STM32 зокрема. Важливо, що, якщо потрібно терміново працювати з файловою системою FAT чи дисплеєм на контролері HD44780, ймовірно, писати їх підтримку самостійно, або, принаймні, писати її з нуля, не доведеться.Крім того, для гурманів, можна спробувати програмувати контролер за допомогою Lua (проект eLua) або Scheme (Armpit Scheme).
Перша програма
Щоб мінімально проілюструвати описане вище (по великому рахунку -- описане за посиланнями вище), розглянемо "Hello world" світу мікроконтролерів -- мигання світлодіодами. Нагадаю, що STM32VLDiscovery має два доступних програмісту світлодіоди, під'єднані до PС8 і PC9.Спершу обмежимося засобами CMSIS:
/* Файл із різноманітними оголошеннями -- іменами регістрів, * бітмасками, адресами відображення в пам'яті, тощо */ #include <stm32f10x.h> int main() { /* Вмикаємо тактування порту C * в регістрі APB2ENR підсистеми * RCC (Reset and Clock Control): * встановлюємо біт RCC_APB2ENR_IOPCEN * */ RCC->APB2ENR |= RCC_APB2ENR_IOPCEN; /* Піни 0-7 порта керуються регістром CRL, * 8-15 -- CRH */ /* Режим: вивід, Push-Pull, біти CNF8 -- нульові, очищаємо*/ GPIOC->CRH &= ~GPIO_CRH_CNF8; GPIOC->CRH &= ~GPIO_CRH_CNF9; /* Частота оновлення -- 2МГц, біти MODE - 10b */ /* Очищаємо MODE0 для PC8 */ GPIOC->CRH |= GPIO_CRH_MODE8_0; /* Встановлюємо MODE1 для PC8 */ GPIOC->CRH &= ~GPIO_CRH_MODE8_1; /* Очищаємо MODE0 для PC9 */ GPIOC->CRH |= GPIO_CRH_MODE9_0; /* Встановлюємо MODE1 для PC9 */ GPIOC->CRH &= ~GPIO_CRH_MODE9_1; /* Встановлюємо 1 на пінах 8 і 9 -- засвічуємо діоди */ GPIOC->BSRR = GPIO_BSRR_BS8; GPIOC->BSRR = GPIO_BSRR_BS9; /* Зависаємо */ while (1) { __NOP(); } }
А тепер повторимо те ж, користуючись SPL:
/* Файл із різноманітними оголошеннями -- іменами регістрів, * бітмасками, адресами відображення в пам'яті, тощо */ #include <stm32f10x.h> /* Функції керування тактуванням * (підсистема RCC -- Reset and Clock Control)
* Частина SPL */ #include <stm32f10x_rcc.h> /* Функції роботи з GPIO, частина SPL */ #include <stm32f10x_gpio.h> int main() { /* Вмикаємо тактування порту C */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); /* Готуємо структуру опису порта: */ GPIO_InitTypeDef LEDS_gpio_conf; /* Режим: вивід, Push-Pull */ LEDS_gpio_conf.GPIO_Mode = GPIO_Mode_Out_PP; /* Піни: 8 і 9 (там у нас світлодіоди) */ LEDS_gpio_conf.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9; /* Частота оновлення: 2МГц (більше і не треба) */ LEDS_gpio_conf.GPIO_Speed = GPIO_Speed_2MHz; /* Ініціалізуємо порт C згідно заданої конфігурації */ GPIO_Init(GPIOC, &LEDS_gpio_conf); /* Встановлюємо 1 на пінах 8 і 9 -- засвічуємо діоди */ GPIO_SetBits(GPIOC, GPIO_Pin_8 | GPIO_Pin_9); /* Зависаємо */ while (1) { __NOP(); } }
Взагалі, на таких маленьких прикладах важко зрозуміти переваги та недоліки кожного із способів, але запідозрити, в чому відмінність, вже можна.
На цьому -- поки все, дякую за увагу і все таке :=)
дякую за хорошу підбірку матеріалів, сам вже перечитав частину вище вказаного)
ВідповістиВидалитиГарна річ.
ВідповістиВидалитиЗара вивчаю SAMD20.