вівторок, 8 листопада 2016 р.

Таймери STM32 -- зміст

Статей про таймери вийшло багато. Щоб краще орієнтуватися, пасує зробити зміст. Потім треба буде його зробити ще й для постів про далекомір. Аналогічний зміст для постів про далекомір.

Проекти із кодом, який використовується в постах, зазвичай можна скачати за посиланням в кінці посту. Історично склалося так, що більшість проектів проекти для CoIDE. В принципі, зараз перейшов на System Workbench for STM32, але якби взявся всі проекти переносити -- написання цих постів точно ніколи б не завершилося.

Розглядається використання CMSIS та HAL+STM32CubeMX. Код Cube та HAL розтинається та аналізується аж до рівня CMSIS -- безпосередньої маніпуляції регістрами.
На жаль, не передбачено простого візуального способу пропустити цей reverse engineering для тих, кому цікаво лише знайти підказку, як скористатися тією чи іншою можливістю. Однак, в тексті все-таки відділяється опис способі використання від аналізу подробиць роботи.



Додатковий крихітний пост серії. Назва говорить сама за себе. ARM Cortex  M0/M3/M4 (не маю поки впевненості щодо нового M7) значно більш передбачувані з точки зору часу виконання інструкцій, ніж x86, тому busy loops із відомою тривалістю писати простіше. Іноді такого підходу досить.

-1 Мікросекундні затримки та відлік мікросекунд для STM32
Більш загальний підхід до підрахунку тактів -- незалежність коду від тактової частоти. Використання для відліку часу DWT та таймерів. Пост написаний після більшості в цій серії, активно користується HAL і таймери. В принципі, практично заміщає собою п .-2.

В одному місці зібрана інформація про цей таймер, що траплялася у інших постах. Так буде зручніше посилатися. Та й ціле простирадло огляду архітектури STM32 проглядати, щоб знайти інформацію про SysTick, а потім ще "Далекомір HC-SR04 -- використовуючи GPIO/CMSIS", щоб подивитися, як його переривання опрацьовувати -- не зручно. Із нового -- кілька рядків про засоби калібрування, на жаль, відсутні в лінійці STM32F1. 

Розповідається,  які таймери бувають у мікроконтролерів сімейств STM32F1xx, STM32F4, STM32F303 і деяких інших. Показано принципи їх функціонування, можливі режими роботи, регістри та бітові поля цих регістрів, які ними керують. Розглянуто більшість режимів використання -- фіксація імпульсів (input capture), генерація сигналів (output compare, PWM), автоматична та аварійна зупинка, тощо. Коротко розповідається про watchdog -- сторожові таймери, як незалежний, так і віконний та RTC -- простенький в STM32F1xx, повноцінний в STM32F303.

2. Таймери STM32 -- відлік часу/CMSIS
Використання таймерів, щоб більш чи менш хитро рахувати такти. Розповідається, як здійснюється обробка та генерація переривань таймерами, показано, як переривання від периферії вмикаються. Розглянуто подію оновлення -- момент, коли таймер записує в лічильник нове значення -- нуль, якщо відлік йде вверх, максимальне значення -- якщо вниз. Показано, як налаштовувати подільник частоти (prescaler) та інтервал між спрацюваннями. 

3. Таймери STM32 -- відлік часу/HAL
Показано, як зробити те, що в попередньому пості, користуючись лише HAL і STM32CubeMX. Крім вирішення цієї задачі, детально розібрано функції ініціалізації, згенеровані "Cube" та код частини використаних в проекті функцій HAL і пов'язаних із ними структур даних. Пинаймні для мене, розуміння на такому рівні сильно спростило використання HAL. Детально розглядається, як відбувається обробка переривань в дусі HAL.

4. Таймери STM32 -- ШІМ/CMSIS
Розповідається, що таке ШІМ, і як попросити таймер генерувати його на одному із  своїх каналів. Розгляд відбувається на класичному прикладі керування яскравістю світлодіода.

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

Описано два основних режими зовнішнього тактування -- від TIx, коли такти приходять через канали таймера і від ETF -- спеціального виводу зовнішнього тактування. З їх використанням реалізовано підрахунок натискань кнопки, під'єднаної до піну відповідного каналу чи піну ETF. Розглянуто дрижання контактів та вбудовану фільтрацію таймерів для боротьби із ним.  Перераховано, як таймер може реагувати на зовнішній сигнал.

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

Те ж, зроблене із використанням HAL. Розглянуто, як його візуально сконфігурувати, показано що (з точки зору розробників STM32CubeMX), тактування від TIx є підлеглим режимом роботи таймера, а від ETF -- просто режимом тактування. Проаналізовано код функцій HAL, для організації синхронізації від TIx: HAL_TIM_SlaveConfigSynchronization(), TIM_SlaveTimer_SetConfig() і TIM_TI1_ConfigInputStage() та розібрано "до регістрів" вже згадувану раніше функцію HAL_TIM_ConfigClockSource() для режиму ETR. Вкотре видно "товщину" абстракції HAL -- на прикладі TIM_ETR_SetConfig(). Хоча, зрозуміло, це виправданий інженерний компроміс між складністю розробки та освоєння, високорівневістю, ефективністю і гнучкістю.

На простому прикладі -- створенні 32-бітного таймера із двох 16-бітних, розповідається про тактування одного таймера від іншого. Розглянуто, які події головного (master) таймера можуть породжувати зовнішній сигнал -- TGRO.

9. Таймери STM32 -- внутрішні тригери/HAL
Те ж, засобами HAL. Розглянуто, як HAL керує налаштуванням генерацією TRGO (функція HAL_TIMEx_MasterConfigSynchronization()) та внутрішнім тактуванням (HAL_TIM_SlaveConfigSynchronization())


10.  Таймери STM32 -- автоматична зупинка/CMSIS
Коротенька нотатка про біт OPM -- коли цей біт встановлено, таймер зупиняється у відповідь на подію оновлення. Використовується для реалізації одноімпульсного режиму, про який розповідається нижче.

11. Таймери STM32 -- автоматична зупинка/HAL
Те ж, повторене засобами HAL.

12. Таймери STM32 -- захоплення вводу/CMSIS
Розглянуто чергову важливу "фічу" таймерів -- здатність захоплювати ввід, тобто фіксувати (в CCRx) момент певної події -- зміни сигналу на піні, контрольованому таймером. Момент фіксується згідно значення лічильника таймера на момент події. Показано, що через асинхронну природу переривань, слід бути акуратним, хоч в таких простих пристроях це простіше, ніж в повноцінних багатопоточних середовищах.

Те ж, засобами HAL. Розглянуто, як HAL ініціалізує канали захоплення (HAL_TIM_IC_Init,  HAL_TIM_IC_ConfigChannel, TIM_TI1_SetConfig) та як рекомендує опрацьовувати переривання від них (HAL_TIM_IC_CaptureCallback). А ось HAL_TIM_ReadCapturedValue() явно проситься бути переписаною на С++ і з шаблонами.


Хитра комбінація режимів захоплення двох каналів та реакції на тригери, яка дозволяє захоплювати ШІМ -- визначати тривалість та заповнення кожного імпульсу. Одне із практичних використань -- власне, автоматизоване визначення тривалості імпульсів. Для наочності заміряються нетипово великі часи -- тривалості натискання кнопки та інтервали між натисканнями.

Те ж, засобами HAL. В принципі, нічого ще не розглянутого в коді не використовується.

Одноімпульсний режим використовується для генерації хитрих сигналів. Ідея його наступна -- у відповідь на подію, (зовнішню чи внутрішню -- від іншого таймера), після вказаної затримки, генерується та чи інша реакція (один період ШІМ, високий рівень, низький рівень, зміна рівня на протилежний і т.д.). Важливою його частиною є розглянутий вище біт OPM. В даному пості продемонстровано обидва випадки -- зовнішньої та внутрішньої подій.

Те ж, засобами HAL. Крім візуальної частини та нагенерованого із неї коду, розглянуто ще одну функцію HAL, HAL_TIM_OnePulse_Start_IT().


18. Таймери STM32 -- remapping/CMSIS
Захід сонця перепризначення пінів вручну.

19. Таймери STM32 -- порівняння розмірів коду для CMSIS i HAL
Оцінка того, що ми втрачаємо з точки зору розміру коду, користуючись HAL -- яка наша плата за зручність.

Взагалі, рік тому (восени 2015-го) мені здавалося, що в цьому місці буде все (а постів планувалося, максимум, штук 5), але планується продовження, то я зміст дописуватиму.

Однак, зробимо поки паузу в розгорнутому введенні в таймери STM32. Наступними постами повернемося, із новими інструментами, до нашого далекоміру. А поки:

Дякую за увагу!

1 коментар: