STM32. 6. Начальная настройка тактирования системной и часовой шины

STM32. 5. Символьный дисплей HD44780

Для работы всем контроллерам, процессорам, цифровым электронным устройствам необходим источник тактовых импульсов. Он может быть как внешний в виде RC цепочки, керамического или кварцевого осциллятора, кварцевого генератора, также может находиться внутри контроллера. STM32 тут не исключение. Данный контроллер имеет множество вариантов тактирования и обладает гибкими и широкими настройками управления тактированием своей периферии.

STM32 и источники тактовых сигналов

STM32 и источники тактовых сигналов

Рассматривать настройку тактирования будем на примере контроллера STM32F100RB, установленного на STM32vlDiscovery. В работе будет использована библиотека Standard Peripheral Library.

Для начала посмотрим на схемы тактирования из даташитов различных контроллеров из семейства stm32.

Дерево тактирования stm32f030xx Дерево тактирования stm32f051xx

Деревья тактирования stm32f030xx и stm32f051xx

Дерево тактирования stm32f103xx Дерево тактирования stm32f407xx

Деревья тактирования stm32f103xx и stm32f407xx

Дерево тактирования STM32F100xx

Дерево тактирования STM32F100xx

Из дерева тактирования контроллера видно, что у него есть две основные цепи тактирования основная (системная) и часовая. Причём обе цепи могут получать тактирования как от внешнего источника тактового сигнала, так и от встроенной RC цепочки. Встроенные RC цепочки позволяют уменьшить количество компонентов в устройстве, меньше потребляют, чем при использовании внешнего источника тактового сигнала, но отличаются малой точностью и имеют температурный дрейф (те или иные отклонения в зависимости от окружающей температуры). Если устройство работает с точной высокоскоростной периферией, то это не лучший вариант. Внешний источник тактовых сигналов отличается большей точностью и стабильностью, но при этом увеличивает количество компонентов, следовательно стоимость устройства и его габариты, но при этом, повторюсь, незаменим, когда требуется высокая точность и стабильность.

Системное тактирование

Рассмотрим тактирование системной части контроллера. Нам доступна встроенная 8МГц RC цепочка HSI. Для работы с ней её для начала нужно включить.

RCC_HSICmd(ENABLE);

Тактирование с неё можно подать напрямую на системную шину SYSCLK

RCC_SYSCLKConfig(RCC_SYSCLKSource_HSI);

в этом случае настройка тактирования основной части будет завершена и тактовая частота системной шины составит 8МГц, чего для простых задач будет вполне достаточно. Так же можно подать тактирование на системную шину через множитель PLLMUL. Для этого нам нужно его включить, выбрать множитель и источник тактового сигнала.

RCC_PLLConfig(RCC_PLLSource_HSI_Div2,RCC_PLLMul_4);
RCC_PLLCmd(ENABLE);

Рассмотрим поподробнее. Первая команда RCC_PLLConfig — имеет два параметра, первый выбирает источник тактирования, для STM32F100xx доступны 2 варианта:

  • RCC_PLLSource_HSI_Div2 — с внутренней HSI RC цепочки 8МГц деленные на 2, т.е. 4МГц.
  • RCC_PLLSource_PREDIV1 — тактовый сигнал с внешнего тактового генератора, прошедший через предделитель PREDIV1, который рассмотрим ниже.

Второй параметр выбирает множитель:

  • RCC_PLLMul_2
  • RCC_PLLMul_3
  • RCC_PLLMul_4
  • RCC_PLLMul_5
  • RCC_PLLMul_6
  • RCC_PLLMul_7
  • RCC_PLLMul_8
  • RCC_PLLMul_9
  • RCC_PLLMul_10
  • RCC_PLLMul_11
  • RCC_PLLMul_12
  • RCC_PLLMul_13
  • RCC_PLLMul_14
  • RCC_PLLMul_15
  • RCC_PLLMul_16

Т.е. мы можем имеющиеся 4МГц умножить в 2-6 раз, т.к. максимальная частота системной шины для используемого в примере камня 24МГц. Есть контроллеры с 32, 72, 180МГц. Но за частотой гнаться не нужно, для каждой задачи лучше использовать свою частоту. Для простых задач вполне хватит малых частот, для ресурсоёмких и вычислительноемких задач частота нужна будет поболее. Также следует учитывать, что с возрастанием частоты увеличивается энергопотребление, тепловыделение и снижается надёжность, повышаются требования к схемотехнике и разводке. Всегда нужно уметь находить золотую середину.

Вернёмся к командам: вторая команда RCC_PLLCmd включает или выключает PLL множитель и имеет всего два значения ENABLE и DISABLE.
Остается только выбрать источником тактирования системной шины PLLCLK.

RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

Таким образом получаем тактовую частоту 16МГц, т.е. RC HSI 8МГц/2*4(множитель PLLMUL)=16МГц.

Так же поподробнее рассмотрим команду RCC_SYSCLKConfig. Данная команда, как уже было сказано выше, выбирает источник тактирования системной шины. Доступно их 3:

Если использовать внешний источник тактовых импульсов, то для начала нам нужно его подключить к контроллеру.

  • RCC_SYSCLKSource_HSI — напрямую от внутренней RC HSI 8МГц цепочки
  • RCC_SYSCLKSource_PLLCLK — от PLLMUL множителя
  • RCC_SYSCLKSource_HSE — напрямую от внешнего осциллятора

Подключение кварцевого резонатора к stm32

Подключение кварцевого резонатора к stm32

Частота резонатора может быть от 4 до 24МГц. Емкость конденсаторов рекомендуется от 5 до 25пФ, подробнее нужно смотреть в документации к резонатору. В качестве резонатора можно применять: кварцевые резонаторы, кварцевые генераторы, керамические резонаторы.

Далее подключаем его в коде.

RCC_HSEConfig(RCC_HSE_ON);

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

RCC_SYSCLKConfig(RCC_SYSCLKSource_HSE);

или через множитель PLLMUL. Правда сначала сигнал пройдёт еще через предделитель PREDIV1, что существенно расширяет диапазон частот системной шины.

RCC_PREDIV1Config(RCC_PREDIV1_Source_HSE, RCC_PREDIV1_Div1);
RCC_PLLConfig(RCC_PLLSource_PREDIV1 ,RCC_PLLMul_3);

Данная конфигурация позволяет получить 24МГц от внешнего осциллятора:
8МГц / 1 (предделитель PREDIV1) *3 (множитель PLLMUL) = 24МГц.

Рассмотрим поподробнее предделитель PREDIV1RCC_PREDIV1Config. Он принимает 2 параметра: источник тактирования и делитель. Источник тактирования для STM32F100RB доступен только один RCC_PREDIV1_Source_HSE. Делителей же поболее:

  • RCC_PREDIV1_Div1
  • RCC_PREDIV1_Div2
  • RCC_PREDIV1_Div3
  • RCC_PREDIV1_Div4
  • RCC_PREDIV1_Div5
  • RCC_PREDIV1_Div6
  • RCC_PREDIV1_Div7
  • RCC_PREDIV1_Div8
  • RCC_PREDIV1_Div9
  • RCC_PREDIV1_Div10
  • RCC_PREDIV1_Div11
  • RCC_PREDIV1_Div12
  • RCC_PREDIV1_Div13
  • RCC_PREDIV1_Div14
  • RCC_PREDIV1_Div15
  • RCC_PREDIV1_Div16

Приведу итоговые коды настроек тактирования воедино:

Для тактирования от встроенной RC HSI 8МГц цепочки напрямую. SYSCLK=8МГц

RCC_DeInit(); //	сброс настроек тактового генератора
RCC_HSEConfig(RCC_HSE_OFF); //	отключение внешнего тактового генератора
RCC_HSICmd(ENABLE); //	включение внутреннего RC HSI 8МГц генератора
RCC_SYSCLKConfig(RCC_SYSCLKSource_HSI); //	На системную шину подаем тактирование с RC HSI 8МГц

Тактирование от встроенной RC HSI 8МГц цепочки через множитель PLLMUL. SYSCLK=16МГц

RCC_DeInit(); //	сброс настроек тактового генератора
RCC_HSEConfig(RCC_HSE_OFF); //	отключение внешнего тактового генератора
RCC_PLLConfig(RCC_PLLSource_HSI_Div2,RCC_PLLMul_4); //	тактирование от HSI с делителем 2: 8 / 2 * 4 = 16МГц
RCC_PLLCmd(ENABLE); //	Включаем PLL
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); //	На системную шину подаем тактирование с множителя PLLMUL

Тактирование от внешнего источника тактового сигнала напрямую. SYSCLK=8МГц

RCC_DeInit(); //	сброс настроек тактового генератора
RCC_HSICmd(DISABLE); //	выключение внутреннего RC HSI 8МГц генератора
RCC_HSEConfig(RCC_HSE_ON); //	включение внешнего тактового генератора
RCC_SYSCLKConfig(RCC_SYSCLKSource_HSE); //	На системную шину подаем тактирование с внешнего резонатора

Тактирование от внешнего осциллятора через предделитель PREDIV1 и множитель PLLMUL. SYSCLK=24МГц

RCC_DeInit(); //	сброс настроек тактового генератора
RCC_HSICmd(DISABLE); //	выключение внутреннего RC HSI 8МГц генератора
RCC_HSEConfig(RCC_HSE_ON); //	включение внешнего тактового генератора
RCC_PREDIV1Config(RCC_PREDIV1_Source_HSE, RCC_PREDIV1_Div1);//	Предделитель PREDIV1: HSE перед множителем PLLMUL
RCC_PLLConfig(RCC_PLLSource_PREDIV1 ,RCC_PLLMul_3); //	тактирование от HSE с PREDIV1 8/1*3 = 24МГц
RCC_PLLCmd(ENABLE); //	Включаем PLL
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); //	На системную шину подаем тактирование с множителя PLLMUL

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

Отмечу, что есть некоторые периферийные узлы, которые тактируются от некоторых источников тактового сигнала напрямую и для их работы нужный им источник тактирования нужно будет включать в любом случае, даже если шина, для которой они предназначены, уже подключена к другому источнику. Например, ответвление от 8МГц HSI RC цепочки FLITFCLK — это тактирование интерфейса доступа к flash памяти контроллера из его программы. Ему HSI необходима, даже если контроллер тактируется от внешнего кварца. Подробнее это будет рассмотрено в статье по доступу к flash памяти контроллера.

Бывают случаи, когда тактовая частота шины превышает частоту тактирования подключенной к ней периферии. Обычно такая периферия снабжается собственными предделителями, которыми следует воспользоваться, чтобы периферия могла корректно работать.

Для контроля системной шины и её источников тактирования у контроллера есть специальный выход тактового сигнала — MCO. Его включение и выбор проверяемого тактового источника выбирается следующей командой — RCC_MCOConfig с параметром:

  • RCC_MCO_NoClock — выключен
  • RCC_MCO_SYSCLK — выход тактирования с системной шины SYSCLK
  • RCC_MCO_HSI — выход тактирования с 8МГц HSI RC цепочки
  • RCC_MCO_HSE — выход тактирования с внешнего основного осциллятора
  • RCC_MCO_PLLCLK_Div2 — выход тактирования с множителя PLLCLK деленный на 2

Выход тактового сигнала MCO расположен на PA8 у STM32F100RB. Так же данный вывод нужно сконфигурировать на выход следующим образом.

GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //	включаем тактирование порта A
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; //	Настраиваем PA8 на выход тактирования с ситемной шины
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //	альтернативный выход с подтяжкой
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //	высокоскоростная работа 50МГц
GPIO_Init(GPIOA, &GPIO_InitStructure); //	инициализация вывода порта
RCC_MCOConfig(RCC_MCO_SYSCLK); //	включаем выход татирования с ситемной шины на вывод MCO (RA8)

После включения MCO получаем с PA8 синусоиду с частотой выбранной шины.

Часовое тактирование.

Как и с системным тактированием тут у нас то же доступно и встроенная LSI RC цепочка на 40КГц, так и возможность подключения внешнего часового кварца LSE, на 32.768КГц. Плюс дополнительным бонусом можно подать тактирование через 128 кратный предделитель тактирования с внешнего основного HSE осциллятора. Это может быть полезно при использовании основного тактового генератора с кратной часовой частотой. Наиболее распространённый и точный вариант — использование внешнего часового кварца.

Подключение кварцевого резонатора к stm32

Подключение кварцевого резонатора к stm32

Подключение часового кварцевого резонатора к stm32

Частота кварцевого резонатора для часового кварца составляет 32.768КГц. Емкость конденсаторов обвязки кварца рекомендуется от 5 до 15пФ, подробнее нужно смотреть в документации на используемый резонатор.

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

RCC_LSEConfig(RCC_LSE_ON);// Включить тактирование от внешнего часового кварца
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);// Выбрать источником тактирования внешний часовой кварц
RCC_RTCCLKCmd(ENABLE);// Включить тактирование часовой тактовой шины

Для начала разрешаем работу внешнему часовому кварцу, затем выбираем тактирование часовой шины контроллера от внешнего часового осциллятора, далее включаем саму часовую шину контроллера.

Источник тактирования выбирается командой RTCCLKConfig, с помощью которой можно выбрать следующие источники тактового сигнала:

  • RCC_RTCCLKSource_LSE — внешний часовой тактовый резонатор
  • RCC_RTCCLKSource_LSI — внутренняя 40КГц LSI RC цепочка
  • RCC_RTCCLKSource_HSE_Div128 — тактирование от внешнего основного тактового генератора через 128 кратный предделитель.

Если использовать встроенную 40КГц RC цепочку, то для начала нужно её включить. Настройка в этом случае будет выглядеть следующим образом:

RCC_LSICmd(ENABLE); // Включение тактирования встроенной LSI RC цепочки
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);// Выбрать источником тактирования внутреннюю LSI RC цепочку
RCC_RTCCLKCmd(ENABLE); // Включить татикрование часовой тактовой шины

На этом настройка часовой шины контроллера заканчивается, но настройка встроенных часов реального времени ещё нет, она будет описана в следующей статье —
STM32. 7. Встроенные часы реального времени (RTC)

9 комментариев »

Alex_EXE | 18.08.2015 | STM32 | 8 025 просмотров

9 комментариев на « STM32. 6. Начальная настройка тактирования системной и часовой шины»

  1. Андрей пишет 18.11.2015 в 03:12 #

    А вопросик можно?
    Если я не настраиваю тактирование вообще, только подключаю клоки на интерфейс, какая будет частота SYSCLK? Какова она по умолчанию? Чем определяется? где настраивается?

    Почему я задаю этот вопрос? мне показалось странным следующее. Ничего не настраиваю, но если вставляю функцию RCC_DeInit(); частота сразу падает.

  2. Alex_EXE пишет 22.11.2015 в 18:40 #

    По моему частота будет около 8 МГц.
    Там есть инициализация по умолчанию. Сначала он, кажется, проверит наличие внешнего кварца (обычно по умолчанию ставят 8МГц), а если его нет, то запустится от внутренней RC цепочки.
    В первых статьях курса по stm32 поэтому вопрос настройки тактирования и пропускал, т.к. есть настройки по умолчанию.

  3. Андрей пишет 25.11.2015 в 01:51 #

    Я кажется разобрался. Тут все заморочено. Вам бы надо это отразить как-то в вашей статье.

    Есть такой файлик: system_stm32f..xx.c. Этот файлик входит в состав CMSIS и у меня, ничего не подозревающего, этот файлик был подключен. А в этом файле как раз и присутствуют функции для настройки тактирования. Основная из них «void SystemInit (void){}». И эта функция вызывается из стартап-файла, того, который keil сам вставляет в проект при его создании. Так вот значит, все что в этой функции прописано — все это и есть настройка тактирования. Вот только чтобы изменить эту настройку, надо глубоко копать документацию, разбираться с регистрами и битами, а затем править эту функцию и др. сопутствующие. Как-то сложновато. При внимательном изучении этого файла я углядел следующую фразу (в начале). This file contains the system clock configuration for STM32F0xx devices, and is generated by the clock configuration tool STM32F0xx_Clock_Configuration_V1.0.0.xls. Ах вот оно что! Такая утилитка действительно есть на сайте STM. Черте-что! Зачем тогда они суют этот файл в CMSIS и прописывают вызов функции из него в startup???!!!
    Чего с этим всем делать? Использовать, а потом поверх этого опять настраивать, как пишете Вы, используя STM32 SPL? Или выкинуть файл system_stm32f..xx.c и подкорректировать startup? Как лучше?

  4. Alex_EXE пишет 25.11.2015 в 11:29 #

    Поразбираюсь ещё, подумаю над этим. В середине декабря.

    Такой файлик да, есть. И в нём прописана начальная инициализация, причём без разницы, какая среда разработки.
    Есть некоторые программы, которые помогают настраивать периферию контроллера, например тот же cube, там, правда не для всех контроллеров, можно на удобной блок схеме настроить систему тактирования. Вот только автогенератор кода мне у него не понравился, поэтому его кодом не пользуюсь.
    Утилиту — STM32F0xx_Clock_Configuration_V1.0.0.xls , не встречал и не искал ещё, гляну.

    Как раз таки так и делаю: сначала позволяю STP произвести начальную конфигурацию МК, а затем сам ручками, как описано в статье, всё что нужно переконфигурирую. Только обидно, что у каждого камня свои особенности и немного команды STP отличаются.

  5. Sova пишет 10.03.2016 в 14:58 #

    Спасибо, чувак

  6. filin пишет 21.06.2016 в 14:55 #

    И тебе спасибо чувак, что ты сказал «спасибо чувак», этому чуваку.

  7. Андрей пишет 14.01.2017 в 05:46 #

    Люди работайте с чипом по человечески без использования всех этих оберток, реально инициализация таймера занимает 6 строчек.

  8. Андрей пишет 14.01.2017 в 05:49 #

    Оговорился системы тактирования.

  9. Андрей пишет 14.01.2017 в 05:53 #

    FLASH->ACR = 0x30 | FLASH_ACR_LATENCY_1; //
    //настраиваем источник тактовых сигналов
    RCC->CR |= RCC_CR_HSEON; //включаем генератор HSE
    while(!(RCC->CR & RCC_CR_HSERDY)); //ожидание готовности HSE
    RCC->CFGR = RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL9 | RCC_CFGR_PPRE1_2; //источник тактовых сигналов для PLL выбираем HSE
    RCC->CR |= RCC_CR_PLLON; //включаем PLL
    while(!(RCC->CR & RCC_CR_PLLRDY)); //ожидание готовности PLL
    RCC->CFGR |= RCC_CFGR_SW_PLL; //выбираем PLL для тактирования

    это под STM32F103C8T6 кварц 8 МГц, тактовая 72, все на максимум. Без настройки USB.

Комментарии RSS

Оставьте отзыв