- •Оглавление
- •Предисловие
- •Почему я написал книгу?
- •Для кого эта книга?
- •Как использовать эту книгу?
- •Как организована книга?
- •Об авторе
- •Ошибки и предложения
- •Поддержка книги
- •Как помочь автору
- •Отказ от авторского права
- •Благодарность за участие
- •Перевод
- •Благодарности
- •I Введение
- •1. Введение в ассортимент микроконтроллеров STM32
- •1.1. Введение в процессоры на базе ARM
- •1.1.1. Cortex и процессоры на базе Cortex-M
- •1.1.1.10. Внедренные функции Cortex-M в ассортименте STM32
- •1.2. Введение в микроконтроллеры STM32
- •1.2.1. Преимущества ассортимента STM32….
- •1.2.2. ….И его недостатки
- •1.3. Краткий обзор подсемейств STM32
- •1.3.1. Серия F0
- •1.3.2. Серия F1
- •1.3.3. Серия F2
- •1.3.4. Серия F3
- •1.3.5. Серия F4
- •1.3.6. Серия F7
- •1.3.7. Серия H7
- •1.3.8. Серия L0
- •1.3.9. Серия L1
- •1.3.10. Серия L4
- •1.3.11. Серия L4+
- •1.3.12. Серия STM32WB
- •1.3.13. Как правильно выбрать для себя микроконтроллер?
- •1.4. Отладочная плата Nucleo
- •2. Установка инструментария
- •2.1. Почему выбирают Eclipse/GCC в качестве инструментария для STM32
- •2.1.1. Два слова о Eclipse…
- •2.2. Windows – Установка инструментария
- •2.2.1. Windows – Установка Eclipse
- •2.2.2. Windows – Установка плагинов Eclipse
- •2.2.3. Windows – Установка GCC ARM Embedded
- •2.2.4. Windows – Установка инструментов сборки
- •2.2.5. Windows – Установка OpenOCD
- •2.2.6. Windows – Установка инструментов ST и драйверов
- •2.3. Linux – Установка инструментария
- •2.3.2. Linux – Установка Java
- •2.3.3. Linux – Установка Eclipse
- •2.3.4. Linux – Установка плагинов Eclipse
- •2.3.5. Linux – Установка GCC ARM Embedded
- •2.3.6. Linux – Установка драйверов Nucleo
- •2.3.7. Linux – Установка OpenOCD
- •2.3.8. Linux – Установка инструментов ST
- •2.4. Mac – Установка инструментария
- •2.4.1. Mac – Установка Eclipse
- •2.4.2. Mac – Установка плагинов Eclipse
- •2.4.3. Mac – Установка GCC ARM Embedded
- •2.4.4. Mac – Установка драйверов Nucleo
- •2.4.5. Mac – Установка OpenOCD
- •2.4.6. Mac – Установка инструментов ST
- •3. Hello, Nucleo!
- •3.1. Прикоснитесь к Eclipse IDE
- •3.2. Создание проекта
- •3.3. Подключение Nucleo к ПК
- •3.5. Изучение сгенерированного кода
- •4. Инструмент STM32CubeMX
- •4.1. Введение в инструмент CubeMX
- •4.1.1. Представление Pinout
- •4.1.2. Представление Clock Configuration
- •4.1.3. Представление Configuration
- •4.1.4. Представление Power Consumption Calculator
- •4.2. Генерация проекта
- •4.2.1. Генерация проекта Си при помощи CubeMX
- •4.2.2. Создание проекта Eclipse
- •4.2.3. Ручное импортирование сгенерированных файлов в проект Eclipse
- •4.3. Изучение сгенерированного кода приложения
- •4.3.1. Добавим что-нибудь полезное в микропрограмму
- •4.4. Загрузка исходного кода примеров книги
- •5. Введение в отладку
- •5.1. Начало работы с OpenOCD
- •5.1.1. Запуск OpenOCD
- •5.1.2. Подключение к OpenOCD Telnet Console
- •5.1.3. Настройка Eclipse
- •5.1.4. Отладка в Eclipse
- •5.2. Полухостинг ARM
- •5.2.1. Включение полухостинга в новом проекте
- •5.2.2. Включение полуохостинга в существующем проекте
- •5.2.3. Недостатки полухостинга
- •5.2.4. Как работает полухостинг
- •II Погружение в HAL
- •6. Управление GPIO
- •6.2. Конфигурация GPIO
- •6.2.1. Режимы работы GPIO
- •6.2.2. Режим альтернативной функции GPIO
- •6.2.3. Понятие скорости GPIO
- •6.3. Управление GPIO
- •6.4. Деинициализация GPIO
- •7. Обработка прерываний
- •7.1. Контроллер NVIC
- •7.1.1. Таблица векторов в STM32
- •7.2. Разрешение прерываний
- •7.2.1. Линии запроса внешних прерываний и контроллер NVIC
- •7.2.2. Разрешение прерываний в CubeMX
- •7.3. Жизненный цикл прерываний
- •7.4. Уровни приоритета прерываний
- •7.4.1. Cortex-M0/0+
- •7.4.2. Cortex-M3/4/7
- •7.4.3. Установка уровня прерываний в CubeMX
- •7.5. Реентерабельность прерываний
- •8. Универсальные асинхронные последовательные средства связи
- •8.1. Введение в UART и USART
- •8.2. Инициализация UART
- •8.3. UART-связь в режиме опроса
- •8.3.1. Установка консоли последовательного порта в Windows
- •8.3.2. Установка консоли последовательного порта в Linux и MacOS X
- •8.4. UART-связь в режиме прерываний
- •8.5. Обработка ошибок
- •8.6. Перенаправление ввода-вывода
- •9. Управление DMA
- •9.1. Введение в DMA
- •9.1.1. Необходимость DMA и роль внутренних шин
- •9.1.2. Контроллер DMA
- •9.2. Модуль HAL_DMA
- •9.2.1. DMA_HandleTypeDef в HAL для F0/F1/F3/L0/L1/L4
- •9.2.2. DMA_HandleTypeDef в HAL для F2/F4/F7
- •9.2.3. DMA_HandleTypeDef в HAL для L0/L4
- •9.2.4. Как выполнять передачи в режиме опроса
- •9.2.5. Как выполнять передачи в режиме прерываний
- •9.2.8. Разнообразные функции модулей HAL_DMA и HAL_DMA_Ex
- •9.3. Использование CubeMX для конфигурации запросов к DMA
- •10. Схема тактирования
- •10.1. Распределение тактового сигнала
- •10.1.1. Обзор схемы тактирования STM32
- •10.1.1.1. Многочастотный внутренний RC-генератор в семействах STM32L
- •10.1.3.1. Подача тактового сигнала от высокочастотного генератора
- •10.1.3.2. Подача тактового сигнала от 32кГц генератора
- •10.2. Обзор модуля HAL_RCC
- •10.2.1. Вычисление тактовой частоты во время выполнения
- •10.2.2. Разрешение Выхода синхронизации
- •10.2.3. Разрешение Системы защиты тактирования
- •10.3. Калибровка HSI-генератора
- •11. Таймеры
- •11.1. Введение в таймеры
- •11.1.1. Категории таймеров в микроконтроллере STM32
- •11.1.2. Доступность таймеров в ассортименте STM32
- •11.2. Базовые таймеры
- •11.2.1. Использование таймеров в режиме прерываний
- •11.2.2. Использование таймеров в режиме опроса
- •11.2.3. Использование таймеров в режиме DMA
- •11.2.4. Остановка таймера
- •11.3. Таймеры общего назначения
- •11.3.1.1. Режим внешнего тактирования 2
- •11.3.1.2. Режим внешнего тактирования 1
- •11.3.2. Режимы синхронизации ведущего/ведомого таймеров
- •11.3.2.1. Разрешение прерываний, относящихся к триггерной цепи
- •11.3.2.2. Использование CubeMX для конфигурации синхронизации ведущего/ведомого устройств
- •11.3.3. Программная генерация связанных с таймером событий
- •11.3.4. Режимы отсчета
- •11.3.5. Режим захвата входного сигнала
- •11.3.5.1. Использование CubeMX для конфигурации режима захвата входного сигнала
- •11.3.6. Режим сравнения выходного сигнала
- •11.3.6.1. Использование CubeMX для конфигурации режима сравнения выходного сигнала
- •11.3.7. Генерация широтно-импульсного сигнала
- •11.3.7.1. Генерация синусоидального сигнала при помощи ШИМ
- •11.3.7.2. Использование CubeMX для конфигурации режима ШИМ
- •11.3.8. Одноимпульсный режим
- •11.3.8.1. Использование CubeMX для конфигурации одноимпульсного режима
- •11.3.9. Режим энкодера
- •11.3.9.1. Использование CubeMX для конфигурации режима энкодера
- •11.3.10.1. Режим датчика Холла
- •11.3.10.2. Комбинированный режим трехфазной ШИМ и другие функции управления двигателем
- •11.3.10.3. Вход сброса таймера и блокировка регистров таймера
- •11.3.10.4. Предварительная загрузка регистра автоперезагрузки
- •11.3.11. Отладка и таймеры
- •11.4. Системный таймер SysTick
- •12. Аналого-цифровое преобразование
- •12.1. Введение в АЦП последовательного приближения
- •12.2. Модуль HAL_ADC
- •12.2.1. Режимы преобразования
- •12.2.1.1. Режим однократного преобразования одного канала
- •12.2.1.2. Режим сканирования с однократным преобразованием
- •12.2.1.3. Режим непрерывного преобразования одного канала
- •12.2.1.4. Режим сканирования с непрерывным преобразованием
- •12.2.1.5. Режим преобразования инжектированных каналов
- •12.2.1.6. Парный режим
- •12.2.2. Выбор канала
- •12.2.3. Разрядность АЦП и скорость преобразования
- •12.2.4. Аналого-цифровые преобразования в режиме опроса
- •12.2.6. Аналого-цифровые преобразования в режиме DMA
- •12.2.6.1. Многократное преобразование одного канала в режиме DMA
- •12.2.6.3. Непрерывные преобразования в режиме DMA
- •12.2.7. Обработка ошибок
- •12.2.8. Преобразования, управляемые таймером
- •12.2.9. Преобразования, управляемые внешними событиями
- •12.2.10. Калибровка АЦП
- •12.3. Использование CubeMX для конфигурации АЦП
- •13.1. Введение в периферийное устройство ЦАП
- •13.2. Модуль HAL_DAC
- •13.2.1. Управление ЦАП вручную
- •13.2.2. Управление ЦАП в режиме DMA с использованием таймера
- •13.2.3. Генерация треугольного сигнала
- •13.2.4. Генерация шумового сигнала
- •14.1. Введение в спецификацию I²C
- •14.1.1. Протокол I²C
- •14.1.1.1. START- и STOP-условия
- •14.1.1.2. Формат байта
- •14.1.1.3. Кадр адреса
- •14.1.1.4. Биты «Подтверждено» (ACK) и «Не подтверждено» (NACK)
- •14.1.1.5. Кадры данных
- •14.1.1.6. Комбинированные транзакции
- •14.1.1.7. Удержание синхросигнала
- •14.1.2. Наличие периферийных устройств I²C в микроконтроллерах STM32
- •14.2. Модуль HAL_I2C
- •14.2.1.1. Операции I/O MEM
- •14.2.1.2. Комбинированные транзакции
- •14.3. Использование CubeMX для конфигурации периферийного устройства I²C
- •15.1. Введение в спецификацию SPI
- •15.1.1. Полярность и фаза тактового сигнала
- •15.1.2. Управление сигналом Slave Select
- •15.1.3. Режим TI периферийного устройства SPI
- •15.1.4. Наличие периферийных устройств SPI в микроконтроллерах STM32
- •15.2. Модуль HAL_SPI
- •15.2.1. Обмен сообщениями с использованием периферийного устройства SPI
- •15.2.2. Максимальная частота передачи, достижимая при использовании CubeHAL
- •15.3. Использование CubeMX для конфигурации периферийного устройства SPI
- •16. Циклический контроль избыточности
- •16.1. Введение в расчет CRC
- •16.1.1. Расчет CRC в микроконтроллерах STM32F1/F2/F4/L1
- •16.2. Модуль HAL_CRC
- •17. Независимый и оконный сторожевые таймеры
- •17.1. Независимый сторожевой таймер
- •17.1.1. Использование CubeHAL для программирования таймера IWDG
- •17.2. Системный оконный сторожевой таймер
- •17.2.1. Использование CubeHAL для программирования таймера WWDG
- •17.3. Отслеживание системного сброса, вызванного сторожевым таймером
- •17.4. Заморозка сторожевых таймеров во время сеанса отладки
- •17.5. Выбор сторожевого таймера, подходящего для вашего приложения
- •18. Часы реального времени
- •18.1. Введение в периферийное устройство RTC
- •18.2. Модуль HAL_RTC
- •18.2.1. Установка и получение текущей даты/времени
- •18.2.1.1. Правильный способ чтения значений даты/времени
- •18.2.2. Конфигурирование будильников
- •18.2.3. Блок периодического пробуждения
- •18.2.5. Калибровка RTC
- •18.2.5.1. Грубая калибровка RTC
- •18.2.5.2. Тонкая калибровка RTC
- •18.2.5.3. Обнаружение опорного тактового сигнала
- •18.3. Использование резервной SRAM
- •III Дополнительные темы
- •19. Управление питанием
- •19.1. Управление питанием в микроконтроллерах на базе Cortex-M
- •19.2. Как микроконтроллеры Cortex-M управляют рабочим и спящим режимами
- •19.2.1. Переход в/выход из спящих режимов
- •19.2.1.1. «Спящий режим по выходу»
- •19.3. Управление питанием в микроконтроллерах STM32F
- •19.3.1. Источники питания
- •19.3.2. Режимы питания
- •19.3.2.1. Рабочий режим
- •19.3.2.2. Спящий режим
- •19.3.2.3. Режим останова
- •19.3.2.4. Режим ожидания
- •19.3.2.5. Пример работы в режимах пониженного энергопотребления
- •19.4. Управление питанием в микроконтроллерах STM32L
- •19.4.1. Источники питания
- •19.4.2. Режимы питания
- •19.4.2.1. Рабочие режимы
- •19.4.2.2. Спящие режимы
- •19.4.2.2.1. Режим пакетного сбора данных
- •19.4.2.3. Режимы останова
- •19.4.2.4. Режимы ожидания
- •19.4.2.5. Режим выключенного состояния
- •19.4.3. Переходы между режимами питания
- •19.4.4. Периферийные устройства с пониженным энергопотреблением
- •19.4.4.1. LPUART
- •19.4.4.2. LPTIM
- •19.5. Инспекторы источников питания
- •19.6. Отладка в режимах пониженного энергопотребления
- •19.7. Использование калькулятора энергопотребления CubeMX
- •20. Организация памяти
- •20.1. Модель организации памяти в STM32
- •20.1.1. Основы процессов компиляции и компоновки
- •20.2.1. Исследование бинарного ELF-файла
- •20.2.2. Инициализация секций .data и .bss
- •20.2.2.1. Пара слов о секции COMMON
- •20.2.3. Секция .rodata
- •20.2.4. Области Стека и Кучи
- •20.2.5. Проверка размера Кучи и Стека на этапе компиляции
- •20.2.6. Различия с файлами скриптов инструментария
- •20.3. Как использовать CCM-память
- •20.3.1. Перемещение таблицы векторов в CCM-память
- •20.4.1. Программирование MPU с использованием CubeHAL
- •21. Управление Flash-памятью
- •21.1. Введение во Flash-память STM32
- •21.2. Модуль HAL_FLASH
- •21.2.1. Разблокировка Flash-памяти
- •21.2.2. Стирание Flash-памяти
- •21.2.3. Программирование Flash-памяти
- •21.3. Байты конфигурации
- •21.3.1. Защита от чтения Flash-памяти
- •21.4. Дополнительные памяти OTP и EEPROM
- •21.5. Задержка чтения Flash-памяти и ускоритель ART™ Accelerator
- •21.5.1. Роль TCM-памятей в микроконтроллерах STM32F7
- •22. Процесс начальной загрузки
- •22.1.1. Программное физическое перераспределение памяти
- •22.1.2. Перемещение таблицы векторов
- •22.1.3. Запуск микропрограммы из SRAM с помощью инструментария GNU MCU Eclipse
- •22.2. Встроенный загрузчик
- •22.2.1. Запуск загрузчика из встроенного программного обеспечения
- •22.2.2. Последовательность начальной загрузки в инструментарии GNU MCU Eclipse
- •22.3. Разработка пользовательского загрузчика
- •22.3.2. Как использовать инструмент flasher.py
- •23. Запуск FreeRTOS
- •23.1. Введение в концепции, лежащие в основе ОСРВ
- •23.2.1. Структура файлов с исходным кодом FreeRTOS
- •23.2.1.2. Как импортировать FreeRTOS с использованием CubeMX и CubeMXImporter
- •23.3. Управление потоками
- •23.3.1. Состояния потоков
- •23.3.2. Приоритеты потоков и алгоритмы планирования
- •23.3.3. Добровольное освобождение от управления
- •23.3.4. Холостой поток idle
- •23.4. Выделение памяти и управление ею
- •23.4.1. Модель динамического выделения памяти
- •23.4.1.1. heap_1.c
- •23.4.1.2. heap_2.c
- •23.4.1.3. heap_3.c
- •23.4.1.4. heap_4.c
- •23.4.1.5. heap_5.c
- •23.4.2. Модель статического выделения памяти
- •23.4.3. Пулы памяти
- •23.4.4. Обнаружение переполнения стека
- •23.5. Примитивы синхронизации
- •23.5.1. Очереди сообщений
- •23.5.2. Cемафоры
- •23.5.3. Сигналы потоков
- •23.6. Управление ресурсами и взаимное исключение
- •23.6.1. Мьютексы
- •23.6.2. Критические секции
- •23.6.3. Обработка прерываний совместно с ОСРВ
- •23.7. Программные таймеры
- •23.7.1. Как FreeRTOS управляет таймерами
- •23.8. Пример из практики: Управление энергосбережением с ОСРВ
- •23.8.1. Перехват холостого потока idle
- •23.8.2. Бестиковый режим во FreeRTOS
- •23.9. Возможности отладки
- •23.9.1. Макрос configASSERT()
- •23.9.2. Статистика среды выполнения и информация о состоянии потоков
- •23.10. Альтернативы FreeRTOS
- •23.10.1. ChibiOS
- •23.10.2. ОС Contiki
- •23.10.3. OpenRTOS
- •24. Продвинутые методы отладки
- •24.1. Введение в исключения отказов Cortex-M
- •24.1.1.1. Как инструментарий GNU MCU Eclipse обрабатывает исключения отказов
- •24.1.1.2. Как интерпретировать содержимое регистра LR при переходе в исключение
- •24.1.2. Исключения отказов и их анализ
- •24.2.1. Представление Expressions
- •24.2.1.1. Мониторы памяти
- •24.2.2. Точки наблюдения
- •24.2.3. Режим Instruction Stepping Mode
- •24.2.4. Keil Packs и представление Peripheral Registers
- •24.2.5. Представление Core Registers
- •24.3. Средства отладки от CubeHAL
- •24.4. Внешние отладчики
- •24.4.1. Использование SEGGER J-Link для отладчика ST-LINK
- •24.4.2. Использование интерфейса ITM и трассировка SWV
- •24.5. STM Studio
- •24.6. Одновременная отладка двух плат Nucleo
- •25. Файловая система FAT
- •25.1. Введение в библиотеку FatFs
- •25.1.1. Использование CubeMX для включения в ваши проекты библиотеки FatFs
- •25.1.2. Наиболее важные структуры и функции FatFs
- •25.1.2.1. Монтирование файловой системы
- •25.1.2.2. Открытие файлов
- •25.1.2.3. Чтение и запись файла
- •25.1.2.4. Создание и открытие каталога
- •25.1.3. Как сконфигурировать библиотеку FatFs
- •26. Разработка IoT-приложений
- •26.2. Ethernet контроллер W5500
- •26.2.1. Как использовать шилд W5500 и модуль ioLibrary_Driver
- •26.2.1.1. Конфигурирование интерфейса SPI
- •26.2.1.2. Настройка буферов сокетов и сетевого интерфейса
- •26.2.2. API-интерфейсы сокетов
- •26.2.2.1. Управление сокетами в режиме TCP
- •26.2.2.2. Управление сокетами в режиме UDP
- •26.2.3. Перенаправление ввода-вывода на сокет TCP/IP
- •26.2.4. Настройка HTTP-сервера
- •26.2.4.1. Веб-осциллограф
- •27. Начало работы над новым проектом
- •27.1. Проектирование оборудования
- •27.1.1. Послойная разводка печатной платы
- •27.1.2. Корпус микроконтроллера
- •27.1.3. Развязка выводов питания
- •27.1.4. Тактирование
- •27.1.5. Фильтрация вывода сброса RESET
- •27.1.6. Отладочный порт
- •27.1.7. Режим начальной загрузки
- •27.1.8. Обратите внимание на совместимость с выводами…
- •27.1.9. …и на выбор подходящей периферии
- •27.1.10. Роль CubeMX на этапе проектирования платы
- •27.1.11. Стратегии разводки платы
- •27.2. Разработка программного обеспечения
- •27.2.1. Генерация бинарного образа для производства
- •Приложение
- •Принудительный сброс микроконтроллера из микропрограммы
- •B. Руководство по поиску и устранению неисправностей
- •Проблемы с установкой GNU MCU Eclipse
- •Проблемы, связанные с Eclipse
- •Eclipse не может найти компилятор
- •Eclipse постоянно прерывается при выполнении каждой инструкции во время сеанса отладки
- •Пошаговая отладка очень медленная
- •Микропрограмма работает только в режиме отладки
- •Проблемы, связанные с STM32
- •Микроконтроллер не загружается корректно
- •Невозможно загрузить микропрограмму или отладить микроконтроллер
- •C. Схема выводов Nucleo
- •Nucleo-F446RE
- •Разъемы, совместимые с Arduino
- •Morpho-разъемы
- •Nucleo-F411RE
- •Разъемы, совместимые с Arduino
- •Morpho-разъемы
- •Nucleo-F410RB
- •Разъемы, совместимые с Arduino
- •Morpho-разъемы
- •Nucleo-F401RE
- •Разъемы, совместимые с Arduino
- •Morpho-разъемы
- •Nucleo-F334R8
- •Разъемы, совместимые с Arduino
- •Morpho-разъемы
- •Nucleo-F303RE
- •Разъемы, совместимые с Arduino
- •Morpho-разъемы
- •Nucleo-F302R8
- •Разъемы, совместимые с Arduino
- •Morpho-разъемы
- •Nucleo-F103RB
- •Разъемы, совместимые с Arduino
- •Morpho-разъемы
- •Nucleo-F091RC
- •Разъемы, совместимые с Arduino
- •Morpho-разъемы
- •Nucleo-F072RB
- •Разъемы, совместимые с Arduino
- •Morpho-разъемы
- •Nucleo-F070RB
- •Разъемы, совместимые с Arduino
- •Morpho-разъемы
- •Nucleo-F030R8
- •Разъемы, совместимые с Arduino
- •Morpho-разъемы
- •Nucleo-L476RG
- •Разъемы, совместимые с Arduino
- •Morpho-разъемы
- •Nucleo-L152RE
- •Разъемы, совместимые с Arduino
- •Morpho-разъемы
- •Nucleo-L073R8
- •Разъемы, совместимые с Arduino
- •Morpho-разъемы
- •Nucleo-L053R8
- •Разъемы, совместимые с Arduino
- •Morpho-разъемы
- •D. Корпусы STM32
- •LFBGA
- •LQFP
- •TFBGA
- •TSSOP
- •UFQFPN
- •UFBGA
- •VFQFP
- •WLCSP
- •E. Изменения книги
- •Выпуск 0.1 – Октябрь 2015
- •Выпуск 0.2 – 28 октября 2015
- •Выпуск 0.2.1 – 31 октября 2015
- •Выпуск 0.2.2 – 1 ноября 2015
- •Выпуск 0.3 – 12 ноября 2015
- •Выпуск 0.4 – 4 декабря 2015
- •Выпуск 0.5 – 19 декабря 2015
- •Выпуск 0.6 – 18 января 2016
- •Выпуск 0.6.1 – 20 января 2016
- •Выпуск 0.6.2 – 30 января 2016
- •Выпуск 0.7 – 8 февраля 2016
- •Выпуск 0.8 – 18 февраля 2016
- •Выпуск 0.8.1 – 23 февраля 2016
- •Выпуск 0.9 – 27 марта 2016
- •Выпуск 0.9.1 – 28 марта 2016
- •Выпуск 0.10 – 26 апреля 2016
- •Выпуск 0.11 – 27 мая 2016
- •Выпуск 0.11.1 – 3 июня 2016
- •Выпуск 0.11.2 – 24 июня 2016
- •Выпуск 0.12 – 4 июля 2016
- •Выпуск 0.13 – 18 июля 2016
- •Выпуск 0.14 – 12 августа 2016
- •Выпуск 0.15 – 13 сентября 2016
- •Выпуск 0.16 – 3 октября 2016
- •Выпуск 0.17 – 24 октября 2016
- •Выпуск 0.18 – 15 ноября 2016
- •Выпуск 0.19 – 29 ноября 2016
- •Выпуск 0.20 – 28 декабря 2016
- •Выпуск 0.21 – 29 января 2017
- •Выпуск 0.22 – 2 мая 2017
- •Выпуск 0.23 – 20 июля 2017
- •Выпуск 0.24 – 11 декабря 2017
- •Выпуск 0.25 – 3 января 2018
- •Выпуск 0.26 – 7 мая 2018
Часы реального времени |
469 |
HAL_StatusTypeDef HAL_RTC_WaitForSynchro(RTC_HandleTypeDef* hrtc);
Однако вызов данной функции необходим тогда и только тогда, когда мы хотим получить доступ к теневым регистрам сразу после системного сброса или выхода из режима пониженного энергопотребления, когда тактовый сигнал SYSCLK все еще находится на минимальной частоте (поскольку он подается от HSI-генератора). Если тактовый сигнал HCLK по меньшей мере в восемь раз выше, чем RTCCLK, то синхронизация теневых регистров происходит за несколько тактов. При использовании процедуры HAL_RTC_WaitForSynchro() важно помнить, что доступ в режиме записи к так называемому резервному домену питания – backup domain (который включает в себя периферийное устройство RTC) по умолчанию отключен для предотвращения повреждения периферийных регистров из-за нестабильного источника питания. Однако процедуре HAL_RTC_WaitForSynchro() необходим доступ в режиме записи к регистрам RTC, и поэтому нам необходимо разрешить доступ в режиме записи к резервному домену питания
с помощью макроса __HAL_RTC_WRITEPROTECTION_DISABLE(), как показано ниже:
1/* Отключение защиты от записи */
2__HAL_RTC_WRITEPROTECTION_DISABLE(&hrtc);
3/* Ожидание, в течение которого теневые регистры синхронизируются */
4HAL_RTC_WaitForSynchro(&hrtc);
5/* Снова включение защиты от записи для предотвращения повреждения регистров. */
6__HAL_RTC_WRITEPROTECTION_ENABLE(&hrtc);
Наконец, можно обойти доступ к теневым регистрам. В этом случае не обязательно ждать времени синхронизации, но согласованность регистров календаря должна проверяться программным обеспечением. Пользователь должен прочитать необходимые значения полей календаря дважды. Затем результаты двух последовательностей чтения сравниваются. Если результаты совпадают, то результат чтения правильный. Если они не совпадают, поля должны быть прочитаны еще раз, и третий результат чтения является действительным. Чтобы обойти теневые регистры, CubeHAL предоставляет функцию:
HAL_StatusTypeDef HAL_RTCEx_EnableBypassShadow(RTC_HandleTypeDef* hrtc);
Чтобы снова включить доступ к теневым регистрам, мы можем использовать функцию:
HAL_StatusTypeDef HAL_RTCEx_DisableBypassShadow(RTC_HandleTypeDef* hrtc);
18.2.2. Конфигурирование будильников
RTC в STM32 предоставляет два будильника, называемых Alarm A и Alarm B, которые имеют одинаковые функции. Будильник может быть сгенерирован в заданное время или/и дату, запрограммированные пользователем. Для конфигурации будильника мы используем функцию:
HAL_StatusTypeDef HAL_RTC_SetAlarm(RTC_HandleTypeDef *hrtc,
RTC_AlarmTypeDef *sAlarm, uint32_t Format);
Часы реального времени |
470 |
В конечном итоге мы можем опросить будильник, пока не произошло событие, используя функцию:
HAL_StatusTypeDef HAL_RTC_PollForAlarmAEvent(RTC_HandleTypeDef *hrtc, uint32_t Timeout);
Будильник может быть сконфигурирован так, чтобы при срабатывании он выдавал специальное прерывание. RTC_Alarm_IRQn – IRQ, связанный с обоими будильниками, и для конфигурации будильника в режиме прерываний мы можем использовать следующую специальную процедуру:
HAL_StatusTypeDef HAL_RTC_SetAlarm_IT(RTC_HandleTypeDef *hrtc,
RTC_AlarmTypeDef *sAlarm, uint32_t Format);
Как и во всех процедурах обработки прерываний CubeHAL, нам нужно вызвать
HAL_RTC_AlarmIRQHandler() из ISR RTC_Alarm_IRQn. Для получения уведомления о событии
будильника, мы можем реализовать соответствующий обратный вызов:
void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc);
Будильник может быть отключен с помощью функции:
HAL_StatusTypeDef HAL_RTC_DeactivateAlarm(RTC_HandleTypeDef *hrtc, uint32_t Alarm);
Структура RTC_AlarmTypeDef, используемая для конфигурации будильника, определена следующим образом:
typedef struct { |
|
|
RTC_TimeTypeDef AlarmTime; |
/* Задает членов времени будильника RTC |
*/ |
uint32_t AlarmMask; |
/* Задает маски будильника RTC. |
*/ |
uint32_t AlarmSubSecondMask; |
/* Задает маски подсекунд будильника RTC. |
*/ |
uint32_t AlarmDateWeekDaySel; |
/* Задает, включен ли будильник RTC на число |
|
|
месяца или на день недели. |
*/ |
uint8_t AlarmDateWeekDay; |
/* Задает число месяца/день недели будильника RTC. */ |
|
uint32_t Alarm; |
/* Задает будильник (A или B). |
*/ |
} RTC_AlarmTypeDef; |
|
|
•AlarmTime: это поле является экземпляром структуры RTC_TimeTypeDef, рассмотрен-
ной ранее, и используется для установки времени будильника.
•AlarmMask: будильник состоит из регистра того же размера, что и счетчик времени
RTC. Когда счетчик RTC совпадает со значением, заданным в регистре будильника, он генерирует событие. Поле AlarmMask определяет критерии сравнения между будильником и регистром времени RTC. Оно может принимать одно или несколько (путем их битового маскирования) значений, указанных в таблице 2. Например, если мы хотим, чтобы будильник сработал в 12:45:03, мы используем значение RTC_ALARMMASK_NONE. Если вместо этого мы хотим генерировать будильник каждый час в заданную минуту и секунду, мы можем использовать значение
RTC_ALARMMASK_HOURS.
Часы реального времени |
471 |
Таблица 2: Доступные маски будильников для настройки их поведения |
|
Значение маски |
Поведение будильника |
|
|
RTC_ALARMMASK_NONE |
Все поля используются при сравнении будильника (например, |
|
будильник срабатывает в 12:45:03) |
RTC_ALARMMASK_SECONDS
RTC_ALARMMASK_MINUTES
RTC_ALARMMASK_HOURS
RTC_ALARMMASK_DATEWEEKDAY
RTC_ALARMMASK_ALL
Секунды не имеют значения при сравнении будильника (например, будильник срабатывает каждую секунду в 12:45)
Минуты не имеют значения при сравнении будильника (например, будильник срабатывает на 3-й секунде каждой
минуты в 12:XX)
Часы не имеют значения при сравнении будильника (например, будильник срабатывает на 3-й секунде каждой 45-й минуты)
День недели (или число месяца, если оно выбрано) не имеет значения при сравнении будильника (например, будильник срабатывает все дни в 12:45:03)
Будильник срабатывает каждую секунду
•AlarmDateWeekDaySel: задает, установлен ли будильник на дату (число месяца) или
на день недели (понедельник, вторник и т. д.). Может принимать значение
RTC_ALARMDATEWEEKDAYSEL_DATE или RTC_ALARMDATEWEEKDAYSEL_WEEKDAY.
•AlarmDateWeekDay: если для поля AlarmDateWeekDaySel установлено значение
RTC_ALARMDATEWEEKDAYSEL_DATE, то для этого поля должно быть установлено значе-
ние в диапазоне 1–31. И, напротив, если поле AlarmDateWeekDaySel установлено в RTC_ALARMDATEWEEKDAYSEL_WEEKDAY, то в этом поле должны быть установлены сим-
вольные константы RTC_WEEKDAY_MONDAY, RTC_WEEKDAY_TUESDAY и т. д.
•AlarmSubSecondMask: регистр подсекунд времени RTC может использоваться для
генерации событий с гранулярностью (масштабом дробления) ниже секунды. Маскируя отдельные биты регистра подсекунд, можно генерировать события каждые 1/128 с, 1/64 с и так далее. Для получения дополнительной информации о возможностях масок и их влиянии на поведение будильника обращайтесь к официальному AN3371 от ST3. Данная функциональность позволяет, например, использовать RTC в качестве генератора временного отсчета для HAL. ST предоставляет такой пример в проектах CubeHAL. Обратитесь к нему за дополнительной информацией.
•Alarm: задает сконфигурированный будильник и может принимать значения
RTC_ALARM_A и RTC_ALARM_B.
18.2.3. Блок периодического пробуждения
В следующей главе мы увидим, что микроконтроллеры STM32 предоставляют возможность выборочного отключения внутренних функций для снижения энергопотребления. Несколько режимов пониженного энергопотребления дают программистам возможность выбирать уровень энергопотребления, который наилучшим образом соответствует их потребностям, особенно при разработке устройств с батарейным питанием.
3 http://www.st.com/content/ccc/resource/technical/document/application_note/7a/9c/de/da/84/e7/47/8a/DM00025071.pdf/files/DM00025071.pdf/jcr:content/translations/en.DM00025071.pdf
Часы реального времени |
472 |
RTC в STM32 имеет периодический блок временного отсчета и пробуждения, который может пробудить систему, когда микроконтроллер работает в режимах пониженного энергопотребления. Данный блок представляет собой программируемый 16-разрядный таймер нисходящего отсчета с автоперезагрузкой. Когда этот счетчик достигает нуля, устанавливается флаг и генерируется прерывание (если разрешено). Блок пробуждения имеет следующие возможности:
•Программируемый таймер нисходящего отсчета с автоперезагрузкой.
•Специальные флаг и прерывание способны вывести устройство из режима пони-
женного энергопотребления.
•Выход альтернативной функции пробуждения, который можно направить на выход будильника RTC (выход распределяется между будильниками Alarm A, Alarm B или блоком пробуждения Wakeup), с конфигурируемой полярностью.
•Полный набор предделителей для выбора желаемого периода ожидания.
Частота отсчета счетчика пробуждения может быть получена либо из источника RTCCLK и, в конечном итоге, дополнительно поделена, либо из тактового сигнала календаря (то есть после асинхронного и синхронного предделителей). Это дает возможность генерировать события пробуждения с частотой от 122 мкс до более 48 дней, когда выбран внешний тактовый сигнал от LSE-генератора.
Для конфигурации события пробуждения, CubeHAL предоставляет функцию:
HAL_StatusTypeDef HAL_RTCEx_SetWakeUpTimer(RTC_HandleTypeDef *hrtc, uint32_t WakeUpCounter, uint32_t WakeUpClock);
где параметр WakeUpCounter устанавливает значение автоперезагрузки (то есть период) счетчика пробуждения, а параметр WakeUpClock задает частоту счетчика, и он может принимать одно из значений, перечисленных в таблице 3.
Таблица 3: Доступные значения параметра WakeUpClock
Источник тактового сигнала |
|
счетчика пробуждения |
Описание |
|
|
RTC_WAKEUPCLOCK_RTCCLK_DIV2 |
Источник тактового сигнала счетчика пробуждения уста- |
|
новлен на RTCCLK/2. |
RTC_WAKEUPCLOCK_RTCCLK_DIV4
Источник тактового сигнала счетчика пробуждения установлен на RTCCLK/4
RTC_WAKEUPCLOCK_RTCCLK_DIV8
Источник тактового сигнала счетчика пробуждения установлен на RTCCLK/8
RTC_WAKEUPCLOCK_RTCCLK_DIV16
Источник тактового сигнала счетчика пробуждения уста-
новлен на RTCCLK/16
RTC_WAKEUPCLOCK_CK_SPRE_16BITS Источник тактового сигнала счетчика пробуждения уста-
новлен на Тактовый сигнал Календаря
RTC_WAKEUPCLOCK_CK_SPRE_17BITS Источник тактового сигнала счетчика пробуждения уста-
новлен на Тактовый сигнал Календаря , и счетчик пробуж-
дения увеличивается на дополнительный бит (поэтому он может считать до 0x1FFFF).
Независимый IRQ (RTC_WKUP_IRQn) связан со счетчиком пробуждения, и его можно разрешить с помощью функции:
Часы реального времени |
473 |
HAL_RTCEx_SetWakeUpTimer_IT(RTC_HandleTypeDef *hrtc, uint32_t WakeUpCounter, uint32_t WakeUpClock);
Как обычно, мы должны вызвать HAL_RTCEx_WakeUpTimerIRQHandler() из ISR и быть готовыми к оповещению о событии пробуждения, реализовав HAL_RTCEx_WakeUpTimerEventCallback(). В противном случае, если использовать счетчик пробуждения в режиме опроса, мы можем использовать HAL_RTCEx_PollForWakeUpTimerEvent() для обнаружения события пробуждения (что не очень полезно, если честно).
18.2.4.Генерация временной отметки и обнаружение несанкционированного доступа
Периферийное устройство RTC подключено к нескольким I/O в зависимости от используемого корпуса. Эти I/O могут использоваться для генерации временной отметки (timestamp) при изменении их состояния. Текущая дата/время сохраняются в специальных регистрах, а также срабатывает соответствующее прерывание, если оно разрешено.
Для конфигурации временной отметки CubeHAL предоставляет функцию:
HAL_RTCEx_SetTimeStamp(RTC_HandleTypeDef *hrtc, uint32_t TimeStampEdge, uint32_t RTC_TimeStampPin);
Параметр TimeStampEdge задает фронт вывода, на котором активирован режим временной отметки. Данный параметр может принимать одно из следующих значений:
RTC_TIMESTAMPEDGE_RISING и RTC_TIMESTAMPEDGE_FALLING. RTC_TimeStampPin задает вводы/вы-
воды, используемые для генерации временной отметки, и может принимать значение RTC_TIMESTAMPPIN_DEFAULT (которое обычно соответствует выводу PC13) или значение
RTC_TIMESTAMPPIN_PA0 или RTC_TIMESTAMPPIN_POS1 для задания альтернативного вывода
(обычно PA0 или PI8).
Чтобы разрешить прерывание, связанное с соответствующим IRQ TAMP_STAMP_IRQn, мы можем использовать функцию:
HAL_RTCEx_SetTimeStamp_IT(RTC_HandleTypeDef *hrtc, uint32_t TimeStampEdge, uint32_t RTC_TimeStampPin);
HAL_RTCEx_TamperTimeStampIRQHandler() является обработчиком, вызываемым из ISR, в то
время как HAL_RTCEx_TimeStampEventCallback() является соответствующим обратным вызовом. Если вместо этого мы хотим использовать функцию временной отметки в режиме опроса, мы можем использовать функцию:
HAL_RTCEx_PollForTimeStampEvent(RTC_HandleTypeDef *hrtc, uint32_t Timeout);
для опроса события временной отметки. Чтобы получить дату/время, сохраненные в регистрах временной отметки, мы можем использовать функцию:
HAL_RTCEx_GetTimeStamp(RTC_HandleTypeDef *hrtc, RTC_TimeTypeDef *sTimeStamp,
RTC_DateTypeDef *sTimeStampDate, uint32_t Format);