- •Оглавление
- •Предисловие
- •Почему я написал книгу?
- •Для кого эта книга?
- •Как использовать эту книгу?
- •Как организована книга?
- •Об авторе
- •Ошибки и предложения
- •Поддержка книги
- •Как помочь автору
- •Отказ от авторского права
- •Благодарность за участие
- •Перевод
- •Благодарности
- •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
12. Аналого-цифровое преобразование
Довольно часто к микроконтроллеру подключают аналоговые периферийные устройства. В цифровую эпоху все еще существует множество устройств, вырабатывающих аналоговые сигналы: датчики, потенциометры, преобразователи и аудиоустройства – это всего лишь несколько примеров аналоговых устройств, генерирующих переменное напряжение, которое обычно находится в определенном фиксированном интервале значений. Считывая это напряжение, мы можем преобразовать его в числовое представление, подходящее для обработки нашей микропрограммой. Например, TMP36 является достаточно популярным датчиком температуры, который вырабатывает изменяющееся напряжение, пропорциональное рабочему напряжению схемы (говорят, что он дает про-
порционально зависимый (ratiometric) выходной сигнал) и температуре окружающей среды.
Все микроконтроллеры STM32 имеют как минимум один аналого-цифровой преобразователь (АЦП) – периферийное устройство, способное получать несколько входных напряжений через специально предназначенный I/O и преобразовывать их в числовое представление. Входные напряжения сравниваются с хорошо известным фиксированным напряжением, также известным как опорное напряжение (reference voltage). Это опорное напряжение может быть либо получено из домена (секции питания) VDDA, или от внешнего генератора фиксированного опорного напряжения в микроконтроллерах с большим количеством выводов (эти микроконтроллеры предоставляют отдельный вывод, называемый VREF+). Большинство микроконтроллеров STM32 предоставляют 12разрядный АЦП. Некоторые из ассортимента STM32F3 имеют даже 16-разрядный АЦП.
В отличие от других периферийных устройств STM32, которые мы видели до сих пор, АЦП могут сильно отличаться между различными сериями STM32 и даже в пределах одного семейства. По этой причине приведем только введение в работу этого полезного периферийного устройства, оставляя читателю ответственность за глубокий анализ АЦП в конкретном микроконтроллере, который он рассматривает.
Прежде чем анализировать функции, предлагаемые АЦП в микроконтроллере STM32 и связанный с ним CubeHAL, будет лучшим кратко рассказать о том, как работает данное периферийное устройство.
12.1. Введение в АЦП последовательного приближения
Почти во всех микроконтроллерах STM32 АЦП реализован как 12-разрядный АЦП, после-
довательного приближения (Successive Approximation Register, SAR)1. В зависимости от вида
1 На момент написания данной главы АЦП, предоставляемый серией STM32F37x, является единственным заметным исключением из этого правила, поскольку он предоставляет более точный 16-разрядный АЦП с сигма-дельта (Σ-Δ) модулятором. Этот тип АЦП не будет рассмотрен в данной книге. Однако процедуры HAL для его использования имеют одинаковую организацию.
Аналого-цифровое преобразование |
366 |
поставки и используемого корпуса, он может иметь различное количество мультиплексированных входных каналов (обычно более десяти каналов в большинстве микроконтроллеров STM32), позволяющих измерять сигналы от внешних источников. Кроме того, также доступны некоторые внутренние каналы: канал для внутреннего датчика температуры (VSENSE), канал для внутреннего опорного напряжения (VREF INT), канал для контроля внешнего напряжения источника питания (VBAT) и канал для мониторинга напряжения ЖК-дисплеев в тех микроконтроллерах, которые нативно предоставляют контроллер монохромных пассивных ЖК-дисплеев (например, STM32L053 является одним из них). АЦП, реализованные в STM32F3 и в большинстве микроконтроллеров STM32L4, также способны преобразовывать полностью дифференциальные входы. В таблице 1 приведено точное количество АЦП и связанные с ними источники входного сигнала для всех микроконтроллеров STM32, оснащающих шестнадцать плат Nucleo, рассматриваемых нами в данной книге.
Таблица 1: Наличие АЦП в микроконтроллерах STM32, оснащающих платы Nucleo
Аналого-цифровое преобразование различных каналов может выполняться в одноканальном, многоканальном (режиме сканирования), непрерывном или прерывистом режимах. Результат АЦП сохраняется в 16-разрядном регистре данных с левым или правым выравниванием. Кроме того, АЦП также реализует функцию аналогового сторожевого таймера, которая позволяет приложению обнаруживать, выходит ли входное напряжение за пределы пользовательских верхнего или нижнего пороговых значений: если это происходит, срабатывает специальный IRQ.
Рисунок 1: Упрощенная структурная схема АЦП
Аналого-цифровое преобразование |
367 |
На рисунке 1 показана структурная схема АЦП. Блок выбора входного канала и управления сканированием выполняет выбор источника входного сигнала для АЦП. В зависимости от режима преобразования (одноканальный, многоканальный или непрерывный режимы) данный блок автоматически переключается между входными каналами, так что каждый из них может быть считан с определенным периодом. Выход этого блока питает АЦП.
На рисунке 1 также показана другая важная часть АЦП: блок управления запуском и остановом. Его роль заключается в управлении процессом аналого-цифрового преобразования, который может запускаться программно или переменным количеством источников входного сигнала. Кроме того, он внутренне подключен к линии TRGO некоторых таймеров, поэтому преобразования могут выполняться автоматически по таймеру в режиме DMA. Мы проанализируем этот важный режим АЦП позже.
Рисунок 2: Внутренняя структура блока SAR ADC
На рисунке 2 показаны основные блоки, формирующие блок АЦП последовательного приближения (SAR ADC), показанный на рисунке 1. Входной сигнал проходит через блок SHA. Как вы могли заметить на рисунке 1, переключатель и конденсатор подключены последовательно ко входу АЦП. Эта часть представляет блок выборки и хранения (Sample-and-Hold, SHA), показанный на рисунке 2, который доступен во всех АЦП. Данный блок играет важную роль, заключающуюся в поддержании неизменным входного сигнала в течение такта преобразования (выборки; дискретизации). Благодаря внутреннему блоку синхронизации, который регулируется конфигурируемым тактовым сигналом, как мы увидим позже, SAR непрерывно подключает/отключает источник входного сигнала, закрывая/открывая «переключатель» на рисунке 1. Чтобы поддерживать уровень напряжения на входе постоянным SHA выполняется в связке с цепью конденсаторов: это гарантирует, что сигнал источника поддерживается на определенном уровне на время аналого-цифрового преобразования, которое требует определенного количества времени, в зависимости от выбранной частоты преобразования (выборки; дискретизации).
Выходной сигнал блока выборки и хранения SHA поступает на компаратор, который сравнивает его с другим сигналом, генерируемым внутренним ЦАП. Результат сравнения отправляется в блок логики, который вычисляет числовое представление входного сигнала в соответствии с хорошо охарактеризованным алгоритмом. Этот алгоритм отличает АЦП SAR от других аналого-цифровых преобразователей.
Алгоритм последовательного приближения вычисляет напряжение входного сигнала путем сравнения его с генерируемым напряжением от внутреннего ЦАП, которое представляет собой часть опорного напряжения VREF: если входной сигнал больше данного
Аналого-цифровое преобразование |
368 |
внутреннего опорного напряжения, то происходит дальнейшее увеличение этого опорного напряжения пока входной сигнал не станет меньше него. Окончательный результат будет соответствовать числу в диапазоне от нуля до максимального 12-разрядного целого беззнакового числа, то есть 212 − 1 = 4095. Предположим, что VREF = 3300 мВ, тогда
получается, что 3300 мВ представляется числом 4095. Это означает, что
Например, входное напряжение, равное 2,5 В, будет преобразовано в:
1 |
= |
3300 |
|
||
10 |
|
4095 |
|
|
0,8
мВ
.
x = |
4095 |
2500 мВ = 3102 |
|
3300 мВ |
|||
|
|
Алгоритм SAR работает следующим образом:
1.Значение в выходном регистре данных обнуляется, а старший значащий бит (MSB) устанавливается в 1. Это значение будет соответствовать четко определенному уровню напряжения, генерируемому внутренним ЦАП.
2.Выходной сигнал ЦАП сравнивается с входным сигналом VIN:
1.если VIN больше, то бит остаётся равным 1;
2.если VIN меньше, то бит возвращается в 0;
3.Алгоритм переходит к следующему MSB-биту в регистре данных, пока все биты не будут установлены в 1 или 0.
На рисунке 3 представлен процесс преобразования, выполняемый блоком логики SAR внутри 4-разрядного АЦП. Рассмотрим путь, выделенный красным цветом, и предположим, что VIN = 2700 мВ и VREF = 3300 мВ. Алгоритм начинается с установки MSB-бита в 1, что соответствует 10002 = 810. Это означает, что:
x = |
3300 мВ |
8 |
= 1760 мВ |
||
|
4 |
|
|||
|
2 |
−1 |
10 |
|
|
|
|
|
|
При значении VIN большем, чем 1760 мВ, 4-й бит остается равным 1, и алгоритм переходит к следующему MSB-биту. Теперь значение в регистре данных равно 11002 = 1210, и ЦАП генерирует выходной сигнал, равный 2640 мВ. Текущее значение VIN все еще больше, чем значение внутреннего напряжения, поэтому третий бит снова остается равным 1. Регистр устанавливается в значение 11102 = 1410, которое соответствует внутреннему напряжению, равному 3080 мВ. На этот раз VIN меньше внутреннего напряжения, и второй бит сбрасывается в ноль. Алгоритм теперь устанавливает 1-й бит в 1, который установит значение внутреннего напряжения равным 2860 мВ. Это значение все еще больше, чем VIN, и алгоритм сбрасывает последний бит в ноль. АЦП обнаруживает, что входное напряжение близко к 2640 мВ. Очевидно, что чем большее разрешение обеспечивает АЦП, тем ближе к VIN будет преобразованное значение.
Как видите, алгоритм SAR, по сути, выполняет поиск в бинарном дереве. Большим преимуществом этого алгоритма является то, что преобразование выполняется за N тактов, где N соответствует разрядности АЦП. Таким образом, 12-разрядный АЦП требует 12 тактов для выполнения преобразования. Но как долго может длиться такт? Количество тактов в секунду, то есть частота АЦП, является параметром оценки производительности АЦП. АЦП последовательного приближения могут быть очень быстрыми, особенно если разрядность АЦП уменьшается (чем меньше бит выборки, тем меньше тактов на преобразование). Однако импеданс источника аналогового сигнала или последовательное сопротивление (RIN) между источником сигнала и выводом микроконтроллера вызывают падение напряжения на нем из-за тока, протекающего в вывод.
Аналого-цифровое преобразование |
369 |
Рисунок 3: Процесс преобразования, выполняемый SAR ADC
Заряд внутренней цепи конденсаторов (которую мы обозначаем CADC) контролируется переключателем на рисунке 1, имеющим сопротивление, равное RADC. С добавлением сопротивления источника (то есть RTOT = RADC + RIN) время, необходимое для полной зарядки накопительного конденсатора, увеличивается. На рисунке 4 показан эффект сопротивления источника аналогового сигнала. На эффективный заряд емкости CADC влияет RTOT, поэтому постоянная времени заряда становится tC = (RADC + RIN) × CADC. Если время выборки (sampling time, или время преобразования; дискретизации) меньше времени, необходимого для полной зарядки CADC через сопротивление RTOT (т.е. tS < tC), то цифровое значение, преобразованное АЦП, будет меньше, чем фактическое значение. В общем, для достижения приемлемой точности необходимо выждать кратное tC время.
Рисунок 4: Влияние сопротивления АЦП на источник аналогового сигнала