Stm8. тактирование контроллера

Stm8. тактирование контроллера

Систему тактирования я уже бегло рассматривал в случае использования SPL. Стандартная периферийная библиотека, на мой взгляд, предлагается фирмой STM в качестве инструмента для быстрого освоения семейства микроконтроллеров STM8, программистами ранее не работавшими с ними. Сейчас я считаю, что она совершенно лишняя. Хотя, в примерах я использую именованные константы взятые из заголовочных файлов SPL.

Документация которая понадобится для прочтения статьи: Reference Manual STM8S — RM0016, глава 9. В качестве целевого микроконтроллера я буду использовать 20-пиновый STM8S103F3P6.

    Содержание:
  1. Система тактирования STM8S, ключевые особенности;
  2. Подключение и отключение периферии к шинам тактирования. Регистры CLK_ICKR, CLK_PCKENR1 и CLK_PCKENR2;
  3. Внутренний высокочастотный генератор HSI. Регистр CLK_CKDIVR;
  4. Подключение внешнего кварца к HSE генератору тактовой частоты. Регистры CLK_ECKR, CLK_CMSR, CLK_SWR и CLK_SWCR;
  5. Модуль безопасности системы тактирования CSS. Регистр CLK_CSSR;
  6. Тактирование микроконтроллера от низкочастотного внутреннего генератора LSI;
  7. Тактирование микроконтроллера от внешнего часового генератора DS3231;

Скачать полные исходники со сборочными файлам и скомпилированными прошивками, можно по ссылке в конце статьи.

1. Система тактирования STM8S, ключевые особенности

Система тактирования микроконтроллеров STM8S представлена на следующей картинке:

    Особенности системы тактирования микроконтроллеров STM8S:
  1. В системе имеется два тактовых генератора, высокочастотный и низкочастотный.
  2. Внутренний низкочастотный генератор — LSI, работает на частоте 128 кГц, и имеет погрешность ±12%. Сторожевой таймер и система автопробуждения тактируется только от него.
  3. В случае AWU — системы автопробуждения, через параметр Option Bytes — CKAWUSEL, возможно назначить внешний источник тактового сигнала HSE с предделителем в качестве источника тактирования AWU.
  4. В роли высокочастотного генератора могут выступать: а) внутренний генератор — HSI работающий на частоте 16 МГц и имеющий предделитель на 1, 2, 4, 8; б) внешний генератор с частотой до 24 МГц для stm8s2xx серии и до 16 МГц для чипов stm8s1xx серии; в) внутренний генератор работающий от внешнего кварца на частотах 1-24(16 для stm8s1xx) МГц.
  5. Система тактирования имеет модуль безопасности CSS которая может отслеживать работу внешнего генератора или кварца и в случае неисправности оных, переключить микроконтроллер на работу от внутреннего генератора с предделителем равным 8, т.е. на частоту 2 МГц.
  6. Все тактовые генераторы могут включаться и отключаться.
  7. Все периферия при старте микроконтроллера, по умолчанию находится в включенном состоянии. Она может быть отключена через регистры CLK_PCKENR1 и CLK_PCKENR2.
  8. Микроконтроллер может подать тактовый сигнал на выход CCO.

Регистры отвечающие из систему тактирования и их значения по умолчанию представлены на следующей таблице:

Дефолтные настройки системы тактирования можно изменять через Options Bytes. Они разные для различных серий STM8S. В случае STM8S103 они выглядят так:

2. Подключение и отключение периферии к шинам тактирования. Регистры CLK_ICKR, CLK_PCKENR1 и CLK_PCKENR2

Начнем с простого. В качестве шаблонного проекта возьмем Blink на таймере TIM4 из предыдущей статьи.

В главной функции main() заменим строки:

на вызов функции следующего содержания:

С этой функцией и будем в дальнейшем работать.

За подключение периферии к шине тактирования отвечают два регистра: CLK_PCKENR1 и CLK_PCKENR2

Т.к. в программе из периферии используется лишь таймер TIM4, в функцию clk_setup() следует добавить строки:

Внутренними генераторам HSI и LSI управляет регистр CLK_ICKR:

В установках по умолчанию для этого регистра, низкочастотный LSI — генератор выключен, а высокочастотный HSI генератор включен. Это установки полностью соответствуют нашим запросам и регистр CLK_ICKR пока можно не трогать.

3. Внутренний высокочастотный генератор HSI. Регистр CLK_CKDIVR

Чип STM8S после включения питания стартует с внутренним 16 МГц генератором тактового сигнала HSI. Выход частоты с него можно менять установкой предделителя fHSI равному 1, 2, 4, или 8. По умолчанию применяется предделитель равный 8.

Частотой процессора можно управлять с помощью предделителя fCPU. По умолчанию он равен 1.

Предделители fHSI и fCPU устанавливаются через регистр CLK_CKDIVR:

Если записать в регистр значение CLK_PRESCALER_HSIDIV1, т.е. ноль, т.о. микроконтроллер будет работать на частоте 16 МГц. Светодиод при этом будет мигать с полупериодом в 1 секунду. Однако если понизить частоту процессора до 1 МГц командой:

то светодиод все-равно будет мигать с полупериодом в 1 секунду. Почему? Т.к. задержка формируется через таймер, и если посмотреть на схему тактирования:

то видно, что предделитель fCPU никак на периферию не влияет. Он влияет только на частоту процессора. Если вместо задержки на таймере и использовать задержку на счетчике, например из примера предыдущей статьи: Передача параметров из Си в ассемблерную функцию, то она уже будет работать должным образом.

4. Подключение внешнего кварца к HSE генератору тактовой частоты. Регистры CLK_ECKR, CLK_CMSR, CLK_SWR и CLK_SWCR

При подключении внешнего кварца, генератору HSE требуется некоторое время для стабилизации частоты. По умолчанию, это время равно 2048 тактам. Это значение можно менять через параметр Option Bytes — HSECNT.

В связи с этим, существует два варианта переключения на HSE: автоматический и ручной.

Автоматический вариант предполагает минимум действий со стороны программиста. Требуется всего пара команд, чтобы указать новый источник тактового сигнала и дать команду коммутатору на переключение на него. Далее микроконтроллер все сделает сам. Он включит генератор HSE, дождется его стабилизации, и после автоматически переключится на него. Пользовательская программа при этом не ждет переключения, она занимается своими делами.

Блок-схема алгоритма представлена на картинке ниже:

Пример программы с реализацией такого алгоритма у меня получился таким:

Здесь таймер настроен на мигание светодиода с полупериодом в 1 секунду, при частоте генератора 2 МГц. Если поставить кварц с другой частотой, то частота мигания светодиода тоже измениться. Ну и конечно же, при «горячем» вынимание кварца, скажем, из беспаячной макетки мигание светодиода остановится.

Для переключения генератора тактового сигнала используется управляющий регистр коммутатора:

Для указания целевого генератора используется регистр CLK_SWR:

После переключения генератора, содержимое регистра CLK_SWR копируется в CLK_CMSR:

Программу можно модифицировать с использованием прерывания для отключения внутреннего генератора HSI:

Если когда-либо потребуется отключить HSE, например после обратного переключения на HSI, тогда следует воспользоваться регистром CLK_ECKR:

Алгоритм для ручного переключения генератора представлен на блок-схеме ниже:

Реализация этого алгоритма у меня получилась такой:

5. Модуль безопасности системы тактирования CSS. Регистр CLK_CSSR

Модуль безопасности системы тактирования CSS позволяет отслеживать работу генератора HSE и при неполадках с его стороны, автоматически переключать такирование на внутренний генератор HSI. При этом для HSI устанавливается предделитель равный 8, генератор HSE отключается, выставляются служебные флаги.

CSS конфигурируется через регистр CLK_CSSR:

Простейший случай использования CSS добавляет всего две строчки к предыдущему примеру:

Обращаю внимание, что перед включением CSS нужно дождаться переключения на HSE.

Можно использовать прерывание чтобы установить свой предделитель HSI при срабатывании CSS. Т.к. прерывание у системы тактирования одно на всех, нужно либо конфигурировать его на какое-то одно событие, либо парсить флаги при входе в обработчик прерывания.

6. Тактирование микроконтроллера от низкочастотного внутреннего генератора LSI

Еще одним интересным вариантом является возможность тактировать микроконтроллер от 128 кГц низкочастотного внутреннего генератора LSI. Генератор имеет погрешность ±12%, так что использование протоколов с четкими временным границами может быть затруднено. С помощью предделителя CPUDIV возможно снижать частоту CPU вплоть до 1 кГц.

Для того что бы задействовать LSI в качестве главного генератора тактовой частоты, необходимо будет выставить в Option Bytes флаг LSI_EN:

Пример Blink’a с полупериодом 1 сек. на генераторе LSI:

7. Тактирование микроконтроллера от внешнего часового генератора DS3231

Кроме внешнего кварца, номинал которого не может быть меньше 1МГц, микроконтроллер STM8S можно тактировать от внешнего генератора тактовой частоты, который лишен этого ограничения. Для подключения используется пин OSCIN, при этом пин OSCOUT остается свободным как GPIO, и может использоваться для других нужд.

Что бы включить поддержку внешнего генератора, в Options Bytes нужно будет выставить флаг EXTCLK:

Генератора у меня под рукой не было, зато был DS3231, у которого имеется пин с меандром на выходе и частотой 32 кГц. Причем это высокоточный тактовый сигнал, в отличии от LSI.

Ну и опять снова Blink уже с тактированием от DS3231:

Заключение. Остался не рассмотренным выход тактовой частоты CCO, я не смог придумать примера его использования кроме синхронизации нескольких микроконтроллеров. Еще я не затронул регулятор напряжения MVR, отключение которого позволяет повысить энергосбережение. Но S-серию я не рассматриваю как энергосберегающую. Все остальное вроде рассмотрел.

Скачать полные исходники со сборочными файлам и скомпилированными прошивками, можно по ссылке .

Микроконтроллеры STM8. Система тактирования.

Микроконтроллеры STM8. Система тактирования.

Здравствуйте,
В прошлый раз мы начали рассматривать таймеры, а сегодня мы с вами разберемся, как устроена система тактирования в STM8S.
По сравнению с AVR, STM8 сильно выигрывает в мощности и гибкости тактирования. Единственный минус – это невозможность тактироваться от кварцев с частотой меньше 1 МГц, но это компенсируется наличием внутреннего низкочастотного генератора. Самым же главным преимуществом STM8 перед AVR является отсутствие FUSE-битов! Все параметры тактирования настраиваются непосредственно по ходу работы программы.
Итак, источниками тактовой частоты у нас могут быть:
— внешний кварцевый резонатор с частотой 1-24МГц (HSEHigh Speed External);
— внешний источник частоты 1-24МГц (HSE-extHigh Speed External);
— внутренний высокоскоростной RC-генератор 16 МГц (HSIHigh Speed Internal);
— внутренний низкоскоростной RC-генератор 128 КГц (LSILow Speed Internal).
Вот так выглядит блок-схема модуля тактирования:

На схеме мы видим, что выбор основной частоты происходит в модуле Master Clock Switch. После него она поступает на периферийные устройства (таймера, SPI, и.т.д.) и через делитель в ЦПУ. При включении основным источником тактовой частоты является HSI с делителем 8, что дает нам рабочую частоту после подачи питании в 16/8=2 МГц. Логично, что при включении процессор начинает работать он внутреннего генератора – ведь внешнего может и не быть. Понижение частоты сделано для того, чтобы процессор мог стартовать при плохом состоянии питания.
Низкоскоростной генератор может как тактировать ЦПУ, так и работать независимо от основных источников тактирования, управляя независимым сторожевым таймером (IWD) и модулем выхода из спящего режима.
Модуль системы тактирования может вызывать два прерывания – по переключению источника тактирования (Master clock source switch event), и по срабатыванию системы обеспечения безопасности тактирования (Clock Security System event).
Сигнал от любого из источников тактирования, независимо от того, является он активным в данный момент, или нет, может быть выведен наружу контроллера на ножку CCO.
Переключить источник тактирования можно вручную или автоматически. О способах переключения можно прочитать в Reference Manual на странице 64. Я произвожу переключение так:
1. Записываем в регистр CLK_SWR значение, соответствующее необходимому источнику тактовой частоты.
2. Ждем стабилизации источника частоты, контролируя бит SWIF в регистре CLK_SWCR.
3. Разрешаем переключение источника установкой бита SWEN в регистре CLK_SWCR.
4. Записываем в регистр CLK_SWR значение, соответствующее необходимому источнику тактовой частоты. При этом устанавливается бит SWBSY в регистре CLK_SWCR и соответствующий источник тактирования запускается. В этот момент микроконтроллер все ещё тактируется от старого источника. После того, как частота стабилизируется, значение из регистра CLK_SWR копируется в CLK_CMSR и происходит переключение источника тактирования.
5. Ждем установки флага SWIF в регистре CLK_SWCR. После его установки вызывается прерывание, если оно разрешено битом SWIEN.

Рассмотрим управляющие регистры модуля тактирования:
Регистр CLK_CMSRClock master status register. Регистр состояния основной частоты. В этом регистре хранится информация о том, какой именно источник тактирования является текущим на данный момент. Регистр предназначен только для чтения, запись в этот регистр не приведет ни к какому результату. Возможные значения регистра:

  • 0xE1: текущий источник тактирования – HSI (значение после сброса);
  • 0xD2: источник тактирования – LSI;
  • 0xB4: источник тактирования – HSE.
Читайте также  Расценки на электрику

Регистр CLK_SWRClock master switch register. Регистр переключения основной частоты. В него производится запись для смены источника тактовой частоты. Константы для ёё выбора такие же, как и в регистре CLK_CMSR. Запись в этот регистр невозможна во время процесса переключения частоты (в этот момент выставлен бит SWBSY в регистре CLK_SWCR).
Регистр CLK_CKDIVRClock divider register. Регистр делителя частоты.

Биты HSIDIV[1:0] выбирают делитель для внутреннего генератора. Возможные значения:

  • 00 – делитель равен 1 (частота не делится);
  • 01 — делитель равен 2;
  • 10 — делитель равен 4;
  • 11 – делитель равен 8.

Биты CPUDIV[2:0] определяют делитель для ЦПУ.
Возможные значения:

  • 000 — fCPU=fMASTER
  • 001 — fCPU=fMASTER/2
  • 010 — fCPU=fMASTER/4
  • 011 — fCPU=fMASTER/8
  • 100 — fCPU=fMASTER/16
  • 101 — fCPU=fMASTER/32
  • 110 — fCPU=fMASTER/64
  • 111 — fCPU=fMASTER/128

Регистр CLK_ICKRInternal clock register. Регистр управления внутренних источников тактирования. Этот регистр отвечает за настройки генераторов HSI и LSI. Рассмотрим его биты:

Бит HSIEN отвечает за включение высокочастотного генератора. По умолчанию он равен единице и генератор включен.
Бит HSIRDY определяет состояние генератора HSI. Если он установлен, то генератор готов к работе.
Установка бита FHWU разрешает быстрый выход из спящих режимов.
Функции битов LSIEN и LSIRDY соответствуют аналогичным для HSI и отвечают за работу низкоскоростного генератора.
Регистр CLK_ECKRExternal clock register. Регистр управления внешним источником тактирования. Этот регистр отвечает за настройки генератора HSE. В нем всего два конфигурационных бита:
HSEEN – установка этого бита включает внешний источник тактирования (кварц или генератор);
HSERDY – этот бит устанавливается аппаратно, и показывает готовность внешнего источника к работе.
Регистр CLK_SWCRSwitch control register. Регистр управления переключением тактовой частоты.

Рассмотрим составляющие его биты:
SWBSY – этот бит устанавливается аппаратно в момент процесса переключения источника тактовой частоты.
SWEN – установка этого бита разрешает пере переключение источника тактовой частоты.
Установка битв SWIEN разрешает прерывание по переключению источника тактовой частоты.
Флаг SWIF устанавливается после переключения источника. В процедуре обработчика прерывания его необходимо очищать.
Регистр CLK_CSSRClock security system register. Регистр управления системой обеспечения безопасности тактирования.

Бит CSSEN включает модуль CSS.
Бит CSSDIE разрешает вызов прерывания по срабатыванию системы обеспечения безопасности тактирования.
Флаг CSSD выставляется при срабатыванию модуля CSS. В процедуре обработчика прерывания его необходимо очищать.
Более подробное описание этого модуля будет ниже.

Самое время потренироваться на кошках. На плате STM8S – Discovery установлен кварц на 16 МГц, его и будем использовать. Изменим программу из предыдущей статьи про таймеры: добавим в нее переключение тактирования на кварц. При этом увеличим предделитель Таймера1, чтобы видеть переключение светодиода, так как частота тактирования таймера увеличится с 2 МГц (значение по умолчанию) до 16 МГц, и мигание светодиода будет незаметно глазу.

У STM8 есть такой замечательный модуль, как CSS (Clock Security System). Он следит за работой кварцевого генератора, и может, в случае выхода его из строя, переключить тактирование на внутренний генератор. При этом делитель входной частоты устанавливается равным 8, что соответствует 2 МГц. Также, в момент переключения устанавливается флаг CSSD (Clock security system detection) в регистре CLK_CSSR и вызывается прерывание по срабатыванию системы обеспечения безопасности тактирования (Clock security system detection interrupt), если оно разрешено флагом CSSDIE (Clock security system detection interrupt enable).
Включается этот модуль установкой бита CSSEN (Clock security system enable) в регистре CSSR. Отредактируем нашу программу так, чтобы она, в случае выхода кварца из строя, автоматически переключалась на HSI, вызывала прерывание и выполняла некие действия.
И здесь я столкнулся с ошибкой в среде программирования. Напомню, я использую IAR Embedded Workbench for STMicroelectronics STM8, версию 1.20. В заголовочном файле iostm8s105s6.h, который я использую, есть такое описание регистра CLK_CSSR:

Смотрим в Reference manual на странице 77 описание этого регистра и удивляемся: биты CSSD и CSSDIE перепутаны местами!
Исправим содержимое этого файла.

И исправим маски чуть ниже.

В общем для всего семейства хидере iostm8.h эта ошибка присутствует тоже. В хидерах для остальных процессоров я не смотрел, но подозреваю, что там присутствует такая же ошибка.
Кроме того, в iostm8s105s6.h отсутствуют номера векторов прерывания для системы тактирования. Возьмем их из iostm8.h и вставим в конец нашего хидера. Выглядят они так:

И с уже поправленным заголовочным файлом напишем нашу программу.

И небольшое видео с демонстрацией работы программы. Для того, чтобы заставить сбоить кварц, я касаюсь обеих его ножек пальцем. Можно также коротить ножки кварца резистором Ом на сто. При сбое кварца видно, что частота мигания диода уменьшается, так как частота тактирования таймера падает с 16 МГц при работе от HSE до 2 МГц при переключении на HSI/8.

На сегодня все, а в следующий раз мы продолжим разбираться с таймерами.

STM8. Урок 2. Тактирование контроллера

Введение

Контроллеры STM8 имеют собственную систему тактирования периферии. Это сделано с целью повышения энергосбережения. Я считаю, главным отличием от STM32 является отсутствие в контроллере STM8 PPL (ФАПЧ), в контроллере присутствует только делитель тактового сигнала. Это позволяет программно понижать тактовую частоту работы ядра и периферии ниже частоты внутреннего или внешнего кварца, тем самым уменьшая энергопотребление. А когда необходимо что-то быстро рассчитать, можно снова поднять частоту ядра.

Хочу еще раз подчеркнуть ядро и настройки в регистрах специально проектировались под язык программирования СИ. Язык Си был в начале спроектирован для CISC архитектуры процессора и организации памяти фон Неймана. В Справочном пособии (RM031) на первых страницах описывается именно такая организация процессора и памяти. Использование SPL библиотеки я считаю обязательным при программировании STM8. Настройка отдельных битов, регистров является приведет к многочисленным ошибкам. Кроме того, SPL библиотека позволяет организовать слой абстракции для быстрой и правильной настройки периферии.

Настройка контроллера должна начинаться с тактирования. С частотой тактирования связанна практически вся периферия, за исключением может быть только SPI интерфейса, DMA, ADC. Забыл сказать, чтобы включить любую периферию на нее надо в начале подать тактирование, иначе работать не будет.

1. Схема тактирования

Я не буду приводить схему тактирования приведенную в RM031, я приведу свою интерпритационную схему тактирования для упрощения понимания настройки.В ней я не буду рассматривать тактирование некоторых дополнительных блоков ЖК-экран, часов реального времени, бипера, сторожевого таймера. На мой взгляд этого только запутает читателя. Если понять принцип, это в этих нюансах можно будет разобраться самостоятельно. Если будет нужно, может быть и сам потом напишу статью про них.

И так начнем. Существуют 4 источника тактового сигнала для тактирования ядра и периферии (почти всей).

  • Внутренний высокочастотный источник RC, 16 МГц
  • Внешний высокочастотный источник
  • Внутренний низкочастотный источник 38кГц
  • Внешний низкочастотный источник (обычно 32768 Гц)

Внешние источники могут иметь следующие настройки:

  • отключены
  • работают от кварцевого резонатора
  • работают от внешнего сигнала

Внутренние источники могут быть только включены или отключены. По-умолчанию Внутренние источники включены.

При загрузке МК тактирование ядра осуществляется от Внутреннего выскочастотного генератора, через предделитель на 8, таким образом ядро работает на 2МГц.

Для смены источника тактирования необходимо:

  • включить Необходимый режим работы внешнего источника (для внутреннего источника не требуется)
  • разрешить Смену источника тактирования
  • выбрать настроенный источник тактирования
  • запретить Смену источника тактирования (для безопасности)

Все. 3 функции, 4 вызова и все настроено. Для безопасности можно включить Модуль слежения за внешним тактовым сигналом. При пропадании внешнего сигнала с HSE МК автоматически переключиться на Внутренний HSI.

Выбор предделителя системного сигнала можно осуществлять в любое время.

Тактовый сигнал от любого генератора можно подавать на ножку CCO (PC4). При этом частоту можно делить, т.о. функция имеет два параметра: источник сигнала и делитель.

Любую периферию необходимо затактировать. Для этого функции необходимо два параметра: название периферии и состояние тактирования (вкл/откл).

В библиотеке SPL еще много функций. Я считаю, для ознакомления и пониманию работы этого достаточно.

Практическая часть

Задача. Настроить мигание светодиода от Внутреннего низкочастотного источника (LSI) с предделителем равным 1 (Sys=38kHz), и Внутреннего высокочастотного источника с предделителем равным 128 (125kHz). Через 10 миганий светодиода PC7 производить смену источника тактирования.

Создадим и настроим проект согласно уроку 1. Название проекта sysclk.

Подключим исходники файлов для управления тактированием и настройкой частоты:

  • stm8l15x_clk.c
  • stm8l15x_gpio.c

Функции и структуру GPIO рассмотрим в следующем уроке.

Откомпилированный проект прикрепляю к уроку.

addelectronics › Блог › Урок 5. Изучаем систему тактирования микроконтроллеров STM8.

Микроконтроллеры STM8 могут тактироваться от трёх источников:

Высокоскоростной внутренний RC генератор (HSI), который работает на частоте 16 МГц —
Низкоскоростной внутренний RC генератор (LSI), который работает на частоте 128KHz
Внешний RC генератор (кварц) который может работать на частоте от 1 до 24 МГц,
Во время изучения микроконтроллеров STM8 мы будем использовать внутренний генератор, который нас вполне устраивает (хочу заметить, что внутренний генератор откалиброван очень хорошо). Конечно внешний кварц давал бы нам большую точность, но до того как мы начнём делать прицензионные часы или ещё что либо, зачем нам лишние детальки на плате? .

Во время старта микроконтроллера, если мы не вносили никакие изменения в регистры, наш внутренний генератор будет работать на частоте 2МГц. Мы же изменим настрой делителя частоты, чтобы наш внутренний генератор начал работать на частоте 16МГц

Алгоритм настройки нашего генератора таков:
-Сброс всех регистров генератора к их начальному значению
-Выбор источника тактирования
-Включение механизма тактирования
— Ожидание стабилизации системы тактирования микроконтроллера

Регистры системы тактирования
Описание регистров часов начать вокруг странице 89 STM8S Reference Manual. В этой статье мы будем запускать через регистры обогатительных от значений мы будем устанавливать. Для описания полного вы должны обратиться к STM8S Reference Manual.

CLK_ICKR – Регистр внутреннего тактирования (Internal Clock Register)

Имя регистра/ Описание
REGAH / Контроль за действиями регулятора внутреннего напряжения, когда чип входит в режим Active-Halt.
LSIRDY/ Устанавливается аппаратно, это бит указывает, готов и стабилен ли LSI. 0 — указывает осциллятор не готов, 1 — указывает, что осциллятор стабилен
LSIEN/ Этот бит определяет, выбран ли в качестве источника синхронизации для микроконтроллера.
FHWU/ Этот бит можно менять в самой программе. Это бит показывает включено ли быстрое пробуждение из Active-Halt режима. 0=отключено, 1=включено
HSIRDY/ Устанавливается и сбрасывается аппаратно, это бит определяет, стабилен и готов к использованию ли внутренний источник тактирования HSI.
HSIEN/ Этот бит можно менять в самой программе. Он определяет, выбран ли HSI в качестве источника тактирования. Также этот бит может быть установлен аппаратно, если требуется принудительная работа от HSI. 0=указывает что HSI не выбран, 1=указывает что HSI выбран.

CLK_ECKR – Регистр внешнего тактирования (External Clock Register)

Имя регистра / Описание
HSERDY/ Состояние внешнего источника тактирования. 0=не готов, 1= готов.
HSEEN/ Включениеотключение внешнего источника тактирования. 0= отключено, 1= включено

CLK_CMSR – Регистр состояния тактового генератора (Clock Master Status Register)
Этот регистр устанавливается и сбрасывается аппаратно и указывает, какой из генераторов выбран в качестве источника тактового сигнала.
Величина Источник тактирования
0xe1 HSI
0xd2 LSI
0xb4 HSE
CLK_SWR – Регистр переключения системного источника тактирования
Этот регистр может изменятся в пользовательской программе и используется для выбора источника тактирования.
Величина Источник тактирования
0xe1 HSI
0xd2 LSI
0xb4 HSE

Читайте также  Таймер обратного отсчета на мк atmega8

CLK_CKDIVR — делитель системной тактовой частоты
Системный тактовый сигнал может быть разделён, чтобы обеспечить более низкую частоту работы ядра микроконтроллера. Этот регистр позволяет установить предделитель для внутреннего источника тактирования (HSI) и предделитель для ядра микроконтроллера .
Имя регистра /Описание
HSIDIV/ Предделитель внутреннего генератора
CPUDIV/ Предделитель частоты ядра

Вот такие значения могут быть использованы в качестве предделителя HSI
Значение / Предделитель
0 / Частота HSI
1 / Частота HIS разделённая на 2
2 / Частота HIS разделённая на 4
3 / Частота HIS разделённая на 8

Вот такие значения могут быть использованы в качестве предделителя для ядра.
Значение / Предделитель
0 / Тактовая частота
1 / Тактовая частота разделённая на 2
2 / Тактовая частота разделённая на 4
3 / Тактовая частота разделённая на 8
4 / Тактовая частота разделённая на 16
5 / Тактовая частота разделённая на 32
6 / Тактовая частота разделённая на 64
7 / Тактовая частота разделённая на 128

CLK_PCKENR1 & CLK_ PCKENR2 – Регистры для тактирования всей периферии
Эти регистры нужны для того, чтобы подавать тактирование на нужную нам периферию – таймеры, биперы, I2C и прочее. Для каждого периферийного устройства там отводится по одному биту. Установленный в единицу бит разрешает тактирование, а сброшенный в ноль — отключает тактирование.

Название регистра / Периферия / Описание

CLK_PCKENR1 / TIM1 / Включение / отключение таймера 1
TIM3 Включение / отключение таймера 2
TIM2/TIM5 Включение / отключение таймера 2/5 (зависит от мк.)
TIM4/TIM6 Включение / отключение таймера 4/6 (зависит от мк.)
UART1/2/3 Включение / отключение UART 1/2/3
SPI Включение / отключение SPI
I2C Включение / отключение I2C
CLK_PCKENR2 / CAN / Включение / отключение CAN шину
ADC Включить / отключить АЦП
AWU Включить / отключить сторожевой таймер

Включённая периферия будет использовать частоту тактового генератора. Отключение тактирования собой службы – отключает её.
CLK_CSSR – Регистр системы безопасности
После включения, CSS начинает пристально следить за тактовым сигналом от HSE. Если он вдруг прервался, выполняются следующие спасательные мероприятия:
— Запускается HSI (если он выключен)и тактирование переключается на него
— HSE выключается
— В CLK_CSSR поднимается флаг AUX, оповещая нас о том, что работает запасной генератор.
— Там-же поднимается флаг CSSD и, если установлен бит CSSDIE, происходит прерывание.
— Все регистры из группы CLK, кроме CLK_CKDIVR, блокируются для записи. Изменить настройки тактирования (кроме делителя) больше нельзя до следующей перезагрузки.

CLK_CCOR – Настраиваемый регистр вывода тактовой частоты
Служит ля вывода тактового сигнала на ножку МК.
CLK_HSITRIMR — Калибровка внутреннего генератора

Ну и теперь маленький пример, который показывает как мы можем работать с системой тактирования.
Для примера, мы просто будем инвертировать состояние пина PD0, и при этом менять настройки тактирования, и на осциллографе будем наблюдать за изменением частоты при установке предделителя.

Вот наш код программы

//
// Устанавливаем частоту работы микроконтроллера 16 МГц от внутреннего генератора
//
void InitialiseSystemClock()
<
CLK_ICKR = 0; // Сбрасываем регистр внутреннего тактирования
CLK_ICKR_HSIEN = 1; // Включаем внутренний генератор HSI
CLK_ECKR = 0; // Отключаем внешний генератор
while (CLK_ICKR_HSIRDY == 0); // Ждём стабилизации внутреннего генератора
CLK_CKDIVR = 0; // Устанавливаем максимальную частоту
CLK_PCKENR1 = 0xff; // Включаем всю периферию
CLK_PCKENR2 = 0xff; // Тоже самое
CLK_CCOR = 0; // Выключаем CCO.
CLK_HSITRIMR = 0; // Turn off any HSIU trimming.
CLK_SWIMCCR = 0; // Set SWIM to run at clock / 2.
CLK_SWR = 0xe1; // Используем HSI в качестве источника тактиров
CLK_SWCR = 0; // Сброс флага переключения генераторов
CLK_SWCR_SWEN = 1; // Включаем переключение на HSI
while (CLK_SWCR_SWBSY != 0); // Пауза, пока произойдёт переключение
>

//
//
//
int main(void)
<
__disable_interrupt(); //запрещаем прерывания намомент инициализации
//
// Инициализируем нашу ножку PD0
//
PD_DDR_DDR0 = 1; // Устанавливаем пин PD0 на выход
PD_CR1_C14 = 1; // Пин работает в режиме push-pull
PD_CR2_C24 = 1; // Частота работы пина до 10МГц
//
// Now setup the system clock
//
InitialiseSystemClock();
__enable_interrupt(); //Разрешаем прерывания
while (1)//Бесконечный цикл переключения нашего пина
<
PD_ODR_ODR4 = 1; // Выдаём единицу (+5В) на пин PD0
PD_ODR_ODR4 = 0; // Выдаём ноль (массу) на пин PD0
>
>

_______________________________________________________________
После подключения осциллографа к нашему пину PD0 мы увидим вот такую картинку. Частота переключения нашего пина – 2,963МГц. (Хочу заметить, что вы никогда не увидите частоту 16МГц на пине, поэтому в нашем примере -частота 2,963МГц, просто показательная, и меняя предделитель частоты, мы увидим как именно она будет меняться)

А теперь, вот что произойдёт, если мы установим предделитель для внутреннего генератора (HSI) равный 2 .
Для этого нам нужно изменить вот эту строчку нашего кода.
___________________________________________________________
CLK_CKDIVR = 0
______________________________________________________

На вот это
______________________________________________________
CLK_CKDIVR = 0;
CLK_CKDIVR_HSIDEV = 1; //Устанавливаем предделитель равный 2
______________________________________________________

Результат нашей работы на картинке ниже. Частота сигнала стала 1,335МГц, то есть около половины нашей первоначальной частоты.

Прошу прощения за некоторые плохо читаемые участки статьи с кодом. Просто драйв2 не позволяет нормально работать с таблицами и форматированием текста.
Спасибо за внимание. Жду лайков и комментариев.

Программирование STM32. Часть 3: Система тактирования

Первое, с чем необходимо разобраться перед дальнейшим изучением микроконтроллеров STM32, является система управления тактированием и сбросом, именуемая RCC. В этой статье мы рассмотрим, как правильно настроить микроконтроллер на работу от внешнего кварцевого резонатора на 8 МГц. Все статьи цикла можно посмотреть тут: http://dimoon.ru/category/obuchalka/stm32f1

Система тактирования в STM32 в сравнении с микроконтроллерами AVR выполнена довольно замысловато. Давайте разбираться.

Содержание:

  • Шины
  • Генераторы
  • Тактирование периферии
  • Источники сигнала SYSCLK
  • HSE и PLL
  • Что еще?
  • Заключение

У микроконтроллеров STM32 все периферийные устройства (порты ввода-вывода, таймеры, интерфейсы SPI, и т.д.) подключены к так называемым шинам, через которые периферия получает тактовый сигнал и обменивается данными с ведущими устройствами шины (например, с процессором).

В STM32F103x8 три основных шины: AHB, APB1 и APB2. На каждой из шин висит определенная группа устройств:

  • AHB: процессорное ядро, память и DMA;
  • APB1: USART2, USART3, I2C1/2, CAN, таймеры TIM2..4;
  • APB2: порты GPIO, АЦП, USART1, TIM1, SPI1.

В даташите на STM32F103x8 есть блок-схема, в которой указано, какая периферия куда подключена:

Рис. 1. Блок-схема микроконтроллеров STM32F103x8 и STM32F103xB

Схема на рис. 1 поначалу может казаться сложной и непонятной, это нормально, со временем все в голове уложится и ощущение непонимания исчезнет.

А еще есть вот такая таблица, в которой так же указаны периферийные устройства и шины, к которым они подключены:

Рис. 2. Таблица шин и периферийных устройств

Можно заметить, что на рис. 2 возле названия шины (AHB, APB1 и APB2) в скобках указана ее максимальная частота. Так как периферийные устройства получают тактовый сигнал от шины, ее частота задает скорость работы подключенных к данной шине устройств. Далее мы рассмотрим, как настроить частоту каждой из шин микроконтроллера.

Еще одной особенностью системы тактирования STM32 является то, что после сигнала сброса микроконтроллера вся периферия находится в отключенном состоянии и на нее не подается тактовый сигнал. Это сделано с целью снижения энергопотребления всего микроконтроллера. Перед началом работы с любым периферийным устройством необходимо разрешить подачу на него тактового сигнала. Как это сделать рассмотрим далее.

Итак, вот основные тезисы, которые необходимо запомнить:

  1. Все периферийные устройства в микроконтроллерах STM32 подключены к шинам (AHB, APB1 и APB2), через которые производится взаимодействие с устройствами и подача на них тактовых сигналов;
  2. Шины микроконтроллера STM32 могут иметь разные частоты тактирования;
  3. Перед началом работы с периферийным устройством необходимо разрешить подачу на него тактового сигнала.

Генераторы

В микроконтроллерах STM32F103x8/B присутствует несколько генераторов тактового сигнала:

Рис. 3. Блок-схема системы тактирования, красными прямоугольниками выделены генераторы тактовых сигналов

Первый из них — встроенный RC-генератор на 8 МГц, который называется High-speed internal (HSI) RC oscillator. После сброса микроконтроллер по-умолчанию тактируется как раз от этого генератора. Основным его плюсом является то, что для работы генератора не нужны ни какие дополнительные внешние компоненты. Однако его минус — плохая стабильность генерируемой частоты: при изменении температуры окружающей среды его частота в 8 МГц будет немного плыть. Для нетребовательных ко временнЫм интервалам устройств это может быть не критично, но в некоторых случаях данная особенность является недопустимой.

Следующий — High-speed external (HSE). Этот генератор является альтернативой HSI. Для его работы нужен внешний кварцевый резонатор на частоту 4-16 МГц. Его главным преимуществом в сравнении с HSI является стабильность генерируемой частоты. Так же, при определенной настройке, вывод OSC_IN можно подключить к источнику готового прямоугольного тактового сигнала без использования резонатора.

Далее Low-speed external (LSE). Этот генератор так же требует внешнего кварцевого резонатора, но только на 32768 Гц. LSE используется только для тактирования встроенных часов реального времени RTC, с помощью которых можно вести отсчет текущего времени, если это нужно.

Последний генератор — это Low-speed internal (LSI) RC oscillator. Это встроенный RC-генератор на 40 КГц. Он не отличается особой точностью, однако у него есть очень важная задача: генерация тактового сигнала для сторожевого таймера МК, который перезапустит систему в случае зависания. А еще от LSI можно тактировать RTC, но скорее всего это ни кто делать не будет

Тактирование периферии

Процессорное ядро и основная часть периферии использует тактовый сигнал SYSCLK.

Рис. 4. Распределение тактового сигнала SYSCLK

После делителя AHB Prescaler тактовый сигнал распределяется между шинами микроконтроллера. Сигнал HCLK поступает в процессорное ядро, память и периферию шины AHB. FCLK так же идет в ядро. Через фиксированный делитель на 8 тактирование подается на системный таймер Cortex System timer. Делитель APB1 Prescaler формирует сигнал тактирования устройств шины APB1, а APB2 Prescaler для устройств APB2.

Тут правда есть небольшая особенность формирования тактового сигнала для таймеров и АЦП.

Рис. 5. Распределение тактового сигнала шины APB1 между устройствами

Рис. 6. Распределение тактового сигнала шины APB2 между устройствами

Тактовый сигнал на таймеры подается следующим образом. Если делитель шины (APB1 Prescaler или APB2 Prescaler) установлен в единицу, то частота тактирования тактирования таймеров (TIMXCLK или TIM1CLK) будет равна частоте шины. Но, если делитель не равен единице, то частота тактирования таймеров будет в 2 раза больше частоты шины (см. рис. 5, 6). Вот так А для АЦП есть свой собственный делитель, который из частоты тактирования шины APB2 формирует сигнал ADCCLK (рис. 6).

Думаю, следует еще обратить внимание на вот эти элементы блок-схемы:

Это есть ни что иное, как устройства подачи тактового сигнала на конкретную периферию (логические элементы 2И). Попробую перерисовать один из них так, чтоб было понятнее, что это и как оно работает:

У каждого периферийного модуля в специальном регистре есть свой бит (SPI1EN, IOPAEN, IOABEN и так далее), при установке которого в единицу разрешается подача на него тактового сигнала. На рис. 8 я привел пример только для тактового сигнала PCLK2 шины APB2, для остальных сигналов (HCLK, PCLK1, TIMXCLK, TIM1CLK) все то же самое.

Источники сигнала SYSCLK

Итак, теперь мы знаем, что основным тактовым сигналом в микроконтроллерах STM32 является SYSCLK. Давайте теперь разберемся, как его получить. В нашем распоряжении 3 варианта: генераторы HSI, HSE и модуль PLL:

Рис. 9. Источники сигнала SYSCLK

После сброса микроконтроллера в качестве источника сигнала SYSCLK по-умолчанию устанавливается встроенный RC-генератор HSI. Прохождение тактового сигнала для этого случая представлено на рис. 10, значения по-умолчанию всех делителей обвел кружочком:

Читайте также  Ветрогенератор с вертикальным ротором

Рис. 10. Конфигурация системы тактирования по-умолчанию

А теперь давайте посчитаем значения всех частот в конфигурации по-умолчанию. Частоты HCLK, FCLK, PCLK1, TIMXCLK, PCLK2, TIM1CLK будут равны 8 МГц, частота Cortex System timer равна 1 МГц, а ADCCLK 4 Мгц.

Если мы хотим задействовать HSE-генератор, то картина будет следующей:

Рис. 11. Выбор генератора HSE в качестве источника тактирования SYSCLK

При использовании кварцевого резонатора на 8 МГц все системные частоты будут такими же, что и в предыдущем случае. Разница только в одном: при использовании генератора HSE стабильность частот лучше, чем при использовании HSI. Однако, если мы хотим получить максимальную производительность всей системы, то нужно в качестве источника SYSCLK использовать блок умножения частоты PLL.

HSE и PLL

В микроконтроллерах STM32 модуль PLL может тактироваться как от HSI генератора, так и от HSE. Существует огромное количество вариантов настройки тактирования системы от PLL. Мы остановимся только на одном, в котором используется HSE и все коэффициенты настроены на максимальную производительность системы:

Рис. 12. Схема прохождения тактового сигнала при использовании PLL совместно с HSE

Кварцевый резонатор выбираем на 8 МГц. Далее, сигнал с HSE без деления (настраивается битом PLLXTPRE) поступает на селектор PLLSRC и потом на PLL. Для того, чтобы из 8-и МГц получить 72 МГц, коэффициент умножения PLL должен быть равен PLLMUL=9. Далее, сигнал с PLL частотой 72 МГц через селектор SW поступает на SYSCLK. Так как процессорное ядро мы хотим тактировать максимальной частотой в 72 МГц, AHB Prescaler устанавливаем равный единице (без деления). Для получения частоты шины APB1, равной 36 МГц, APB1 Prescaler ставим равным 2. Шина APB2 имеет максимальную частоту 72 МГц, следовательно, APB2 Prescaler можно установить в 1.

  • Кварц HSE на 8 МГц
  • PLLXTPRE: без деления
  • PLLSRC: HSE генератор
  • PLLMUL = 9
  • SW = PLLCLK
  • AHB Prescaler = 1
  • APB1 Prescaler = 2
  • APB2 Prescaler = 1

Что еще?

Здесь мы не рассмотрели еще некоторые блоки системы тактирования, о которых хочется упомянуть.

Clock security system (CSS) — переводится примерно как «система безопасности тактирования». Если, при использовании генератора HSE в качестве источника тактового сигнала для SYSCLK или PLL, произойдет срыв генерации HSE, то CSS автоматически переключит всю систему на работу от встроенного RC-генератора HSI. Таким образом, если что-то случится с кварцем, система не зависнет намертво в неопределенном состоянии, а сможет выполнить какие-то действия, например, перевести объект управления в безопасное состояние (закрыть все вентили, отключить силовые установки, и т.д.)

Модуль часов реального времени RTC может тактироваться от встроенного LSI генератора на 40 КГц, от HSE через делитель на 128, либо от LSE с внешним кварцем на 32768 Гц. Источник тактовых импульсов выбирается с помощью RTCSEL.

Модуль USB получает тактовый сигнал от PLL, причем при частоте на выходе PLL равной 72 МГц есть возможность активировать USB Prescaler с коэффициентом деления 1.5 для получения необходимой частоты 48 МГц.

Microcontroller clock output (MCO) — вывод микроконтроллера, на который можно вывести частоту от одного из источников сигнала: SYSCLK, HSE, HSI либо сигнал с выхода PLL, поделенный пополам. Нужный источник выбирается с помощью битов MCO.

Заключение

Итак, мы рассмотрели основные моменты в системе тактирования микроконтроллеров STM32 на примере STM32F103x8 и STM32F103xB. В других микроконтроллерах STM32 примерно все то же самое, за исключением некоторых нюансов. В следующей части мы познакомимся с регистрами системы тактирования и сброса RCC и рассмотрим пример инициализации RCC.

stm8l adc определение напряжения питания мк

Контроллеры STM8L15х имеют на борту 12-и разрядный АЦП, который может работать в нескольких режимах, и поддерживает работу с контроллером DMA, что позволяет оцифровать и сложить в память кучу данных без участия ядра.

Здесь я попытался собрать как можно больше информации об АЦП в STM8, чтобы не пришлось бегать по другим статьям в поисках кода для настройки таймера, или, например, DMA. Вот, что описано в статье:
— Настройка АЦП
— Выполнение преобразований в разных режимах
— Настройка внешнего триггера для запуска преобразования
— Настройка таймера для работы совместно с АЦП
— Использование встроенного датчика температуры
— Настройка контроллера DMA для работы вместе с АЦП
— Использование Analog Watchdog

Семейство STM8S не рассматриваем — там все сильно по-другому. А в STM8L101 АЦП вообще нет.

Для начала, ТТХ преобразователя:
— Программируемое разрешение: 6, 8, 10 или 12бит (снижение разрешения позволяет увеличить скорость работы)
— До 28 внешних каналов. Но в том МК, что стоит на STM8L-Discovery, их «всего» 25.
— Плюс еще два внутренних канала: термодатчик и опорное напряжение.
— Два основных режима работы:
1) Одиночное преобразование
2) Последовательное чтение нескольких каналов, с переброской данных в буфер силами DMA. При этом МК не отвлекается на переключение каналов или запись данных в буфер.
— Внешние и внутренние триггеры.
— В качестве опорного напряжения выступает либо пин Vdda, либо ножка Vref+ (в таком случае напряжение на ней должно быть > 2.4V). В дискавери VREF наглухо прибита к питанию.

Настройка

Перед началом работы неплохо-бы разобраться, как его включить. Как и с другой периферией, на АЦП надо подать тактирование. За это отвечает самый первый бит в регистре CLK_PCKENR2:

Изначально АЦП находится в спящем режиме. Чтобы его разбудить, надо поднять бит ADON в регистре ADC_CR1. Но сразу-же начинать преобразование нельзя — нужно подождать примерно 3мкс, пока преобразователь проснется.

Если АЦП будет простаивать некоторое время без дела, то он сам уйдет в спящий режим. Это «некоторое время» — Tidle — обычно равно 1 сек, но может резко уменьшиться с ростом температуры.

После того, как АЦП проснулся, надо выбрать каналы, с которых мы хотим оцифровать сигнал. Можно выбрать сразу несколько каналов через регистры ADC_SQR1 — ADC_SQR4. Биты СHSEL_Sx в них отвечают за каждый канал. Для выбора канала просто устанавливаем соответствующий бит (если установить несколько, то они будут обрабатываться начиная с младшего). Биты CHSEL_STS и CHSEL_SVREFINT отвечают за выбор термодатчика и опорного напряжения соответственно.

В заголовочном файле stm8l15x.h регистры ADC_SQRx организованы в массив, поэтому нумерация начинается с 0. Например, вот так

ADC1->SQR[3] |= (1 «Register map» -> «Factory conversion registers». Например для МК на STM8L-Discovery этот адрес 0x4910. В заголовочных файлах этот адрес не упоминается, поэтому если мы хотим прочитать значение опорного напряжения, то нужно прописать адрес. Примерно так:

И далее, читаем как обычный регистр:

Старший байт этого значения всегда равен 0x06, а по адресу VREFINT_Factory_CONV находится младший.

Для того, чтобы опорное напряжение можно было замерить через АЦП, нужно установить бит VREFINTON в регистре ADC_TRIGR1.

После этого можно измерять напряжение через канал VREFINT (Пятый бит в ADC_SQR1).

Используя значение опорного напряжения можно скорректировать результат преобразования:

В этой формуле
Din — измеренное напряжение
Vrefint — значение опорного напряжения в вольтах. Взятое из даташита или измеренное ранее.
Drefint — результат замера опорного напряжения.

Заменив в этой формуле Din на максимальное значение для данного разрешения (1023 для 10 бит, 4095 для 12 бит . ) мы получим в результате значение опорного напряжения АЦП. А если оно подключено к пину Avcc, то таким образом можно довольно точно определить напряжение питания.

Это может быть полезно в случае устройства, которое питается от батарей безо всяких преобразователей. Или, если устройство может питаться от нескольких источников с разным напряжением — можно определять от какого источника девайс питается в данный момент.

Использование DMA

Часто возникает необходимость собрать кучу выборок с АЦП в оперативку. Для этого можно использовать контроллер DMA. В отличие от ручной переброски данных в RAM, тут от нас требуется только настроить DMA правильным образом и запустить АЦП.

Вся работа DMA сводится к тому, что при завершении преобразования он забирает данные из регистров ADC_DRH и ADC_DRL, записывает их в буфер по указаному адресу, и инкрементирует этот адрес. При этом контроллер DMA отсчитывает количество байт, которые уже записаны. Как только записалось нужное количество — происходит прерывание.

Нам понадобится буфер, куда DMA будет складывать данные:

Названия битов и регистров DMA в заголовочном файле STM8L15x.h соответствуют даташиту чуть менее, чем никак. Непонятно для чего STшники так сделали, но догадываться о назначении того или иного бита приходится только по описанию.

Теперь настраиваем DMA:

После запуска АЦП, DMA будет складывать результаты преобразования в массив recv_array. Когда он заполнится — сработает прерывание Transaction Complete. Если прерывание не нужно, то бит DMA_CCR_TCIE должен быть сброшен.

Если разрядность АЦП 8 или 6 бит (то-есть результат помещается в регистр ADC_DRL), то строчку:

Из процедуры настройки можно убрать. А при указании адреса регистра,

цифру 4 заменить на 5. Тогда DMA будет считывать 1 байт из регистра ADC_DRL (который имеет смещение 5 относительно базового адреса АЦП) и записывать его в массив.

Еще можно установить бит CIRC в регистре CCR. В этом случае при заполнении буфера DMA не остановится, а начнет заполнять его с начала, перезаписывая старые данные

При этом можно отключить прерывания и наслаждаться тем, что в буфере постоянно находятся свежие данные с каналов (ядро в их обновлении не участвует).

Надо отметить, что если включен режим непрерывного преобразования (бит CONT), но при этом не установлен бит CIRC, то при заполнении буфера DMA остановится, но АЦП продолжит работать. Данные при этом никуда сохраняться не будут.

В этом примере при помощи DMA данные с 4 каналов (1,2,3,4) складываются в массив в оперативной памяти.

Каналы соответствуют следующим пинам:
1 — A5
2 — A4
3 — C7
4 — C4

Analog Watchdog

АЦП имеет одну полезную фичу — мониторинг напряжения на каком-либо канале.
Работает она так:
После завершения преобразования сравнивается номер текущего канала с тем, который нужно отслеживать. Если они совпали, то результат преобразования сравнивается с двумя порогами — нижним и верхним. Если результат больше верхнего порога или меньше нижнего, то поднимается флаг AWD в регистре ADC_SR. Можно установить бит AWDIE в ADC_CR1, тогда analog watchdog сможет вызывать прерывание.

Флаг AWD нужно опускать вручную, записав в него 0. Это создает проблему: момент, когда напряжение выходит за установленные рамки мы отловить можем, а вот вернулось-ли оно обратно в эти рамки придется проверять вручную.

Канал, который будет отслеживать analog watchdog выбирается через биты CHSEL[4:0] в регистре ADC_CR3. Значение 0 соответствует нулевому каналу, 1 — первому, и т.д. Через регистры ADC_HTRH и ADC_HTRL настраивается верхний порог, а через ADC_LTRH и ADC_LTRL — нижний.

Значения порогов записываются с учетом текущего разрешения АЦП. Например 1/4 опорного напряжения это 64 для разрешения 8 бит, или 1024 для разрешения 12 бит.

Настройку порогов и выбор канала нужно проводить до запуска АЦП.

Вот таким образом можно настроить Analog Watchdog (предполагается, что АЦП уже настроен):

Теперь можно либо мониторить бит AWD в ADC_SR (если прерывание не используется),

либо ждать прерывание. В его обработчике нужно будет сбросить бит AWD, записав в него 0:

На этом всё. Работа с АЦП во всех возможных режимах описана, примеры для быстрого старта и «для поиграццо» есть. Остался один вопрос — в следующий раз описывать сабж так-же подробно, или достаточно короткого описания, как в статье про lcd?