STM Урок 166. CMSIS. STM32F1. RCC. Часть 2



В предыдущей части урока мы изучиkb устройство RCC, а также познакомились с его основными регистрами.

 

Сначала напомню то, что схема наша со времён прошлого урока не изменилась

 

 

Проект мы также сделаем из проекта прошлого урока с именем BLINK01_CMSIS и назовём его CMSIS_RCC.

Напомню, как мы делаем проект из другого для Keil без Cube MX.

Создадим папку с новым названием

 

 

Скопируем в неё все папки из архива с проектом-донором, а файлы только главные два с настройками проекта

 

 

Затем переименуем эти два файла в новое имя

 

 

Файл с зелёной иконкой (с расширением uvprojx) откроем в блокноте и исправим там старое имя на новое вот здесь

 

 

Также нужно будет изменить имя старое на новое в строке создания файла bin. Можно сделать это и в блокноте, а можно и потом в настройках проекта уже в Keil. Сделаем это сейчас здесь, в файле

<UserProg1Name>fromelf —bin —output .ObjectsCMSIS_RCC.bin .ObjectsCMSIS_RCC.axf</UserProg1Name>

Когда я снимал видео прошлого урока, у меня не формировался файл bin из-за того, что вместо двух тире (минусов) WordPress на сайте подменил их в одно длинное, которое скопировалось в строку в кейле, как одно короткое, так что не забывайте, что перед bin и output не длинное тире, а именно два коротких.

Вот и всё по преобразованию проекта в новый с новым именем.

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

 

uint8_t time2_count = 0;

 

Прежде чем начинать инициализацию RCC, советуют сбросить его настройки, то есть проделать обратную операцию — деинициализацию.

Поэтому добавим вот такую функцию, пока пустотелую

 

 

 

Включим для начала HSI (внутренний генератор 8 МГц)

 

 

Дождёмся его стабилизации

 

 

Сбросим калибровку

 

 

Полностью очистим конфигурационный регистр

 

 

Дождёмся очистку бита SWS

 

 

Аналогичным образом отключим PLL

 

 

Выключим HSE и его детектор тактового сигнала, дождавшись затем отключения HSE

 

 

 

Сбросим бит, разрешающий использование внешнего генератора

 

 

Сбросим флаги всех прерываний от RCC

 

 

Также запретим все прерывания от RCC

 

 

Вызовем нашу функцию в функции main()

 

 

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

Отсюда сделаем вывод, что без настройки RCC у нас контроллер работал вообще на какой-то непонятной частоте. Хотя можно всё это просчитать, внимательно просмотрев в документации настройки битов по умолчанию и выявить, что включено. Но мы этого делать не будем.

Для лучшего эффекта и для оценки преимущества генератора HSE немного исправим величину задержки в бесконечном цикле

 

LED10_OFF(); LED1_ON(); delay(650000);

LED1_OFF(); LED2_ON(); delay(650000);

LED2_OFF(); LED3_ON(); delay(650000);

LED3_OFF(); LED4_ON(); delay(650000);

LED4_OFF(); LED5_ON(); delay(650000);

LED5_OFF(); LED6_ON(); delay(650000);

LED6_OFF(); LED7_ON(); delay(650000);

LED7_OFF(); LED8_ON(); delay(650000);

LED8_OFF(); LED9_ON(); delay(650000);

LED9_OFF(); LED10_ON(); delay(650000);

 

После этого светодиоды будут мигать примерно раз в секунду.

Теперь добавим функцию инициализации RCC в режиме работы от HSE с настройкой системной частоты 72 МГц, которая является максимальной для нашего контроллера

 

 

Включим наш HSE, дождавшись его стабилизации

 

 

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

 

 

Настроим значения всех делителей

 

 

Настроим PLL на коэффициент 9 и настроим его вход для работы от HSE

 

 

Разрешим работу PLL, дождавшись затем его разблокировку

 

 

Выберем PLL в качестве источника системного тактирования, дождавшись затем применения данного действия

 

 

Вызовем нашу функцию в функции main()

 

 

Соберём код, прошьём контроллер и увидим, что наши светодиоды теперь побегут с такой скоростью, что за секунду будут пробегать почти весь цикл (см. видеоверсию), что свидетельствует о том, что наш контроллер теперь действительно тактируется частотой 72 Мгц

 

 

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

Всем спасибо за внимание!

 

 

Предыдущая часть Программирование МК STM32 Следующий урок

 

Исходный код

 

 

Отладочную плату STM32F103C8T6 можно приобрести здесь STM32F103C8T6

Программатор недорогой можно купить здесь ST-Link V2

 

 

Смотреть ВИДЕОУРОК (нажмите на картинку)

 

STM CMSIS. STM32F1. RTC

7 комментариев на “STM Урок 166. CMSIS. STM32F1. RCC. Часть 2
  1. Sergey:

    А не проще отредактировать файл RTE_Device.h в Keil?

    • Не проще чего? Предложение не закончено. «Не проще …, чем…»
      Проектов сотни, поконкретнее, пожалуйста.

      • Sergey:

        Не проще чем расставлять биты, следить за флагами. Я не гуру в вопросах программирования STM, пока только учусь. И учусь по в том числе и по Вашим занятиям, за которые отдельное большое СПАСИБО.
        Но мне кажется проще отредактировать файл RTE_Device.h, который создаётся Keil, при установке галочки «Startup» (Вы упоминали этот пунктик на своих занятиях). И на вкладке «Configuration Wizard», которая становится доступной при редактировании RTE_Device.h прописать все частоты работы STM

  2. Александр:

    «Разрешим работу PLL, дождавшись затем его разблокировку
    SET_BIT(RCC->CR, RCC_CR_PLLON);
    while(READ_BIT(RCC->CR, RCC_CR_PLLRDY) != (RCC_CR_PLLRDY)) {}»

    Поправьте меня пожалуйста если я не прав.
    Но в этой строчке мы разрешаем работу PLL и дожидаемся его БЛОКИРОВКУ.
    т.к.
    PLLRDY (PLL clock ready flag): флаг готовности PLL. Устанавливается аппаратно для блокирования RCC
    0 — PLL разблокирован
    1 — PLL заблокирован.
    и в цикле while мы именно и ждём когда бит RCC_CR_PLLRDY станет единицей что бы провести ложную операцию неравенства и выйти из цикла.
    Если упростить.
    while( 1 != 1 ) {}

    • Микола:

      В цикле мы спрашиваем (логическое побитовое И над содержимым регистра RCC_CR и битовой маской RCC_CR_PLLRDY == 0?). И пока мы на этот вопрос отвечаем ДА — остаемся в цикле while.

  3. Подскажите почему мы именно это число 0х80U == 0b10000000 записываем в битовое поле, нельзя ли просто записать нули?

  4. Макс:

    У вас ошибка где MODIFY_REG(RCC->CFGR, RCC_CFGR_SW, RCC_CFGR_SW_PLL); вы там противоположное задуманному сделали вы включаете RCC_CFGR_SW и отключаете RCC_CFGR_SW_PLL
    то есть вы отключаете PLL там цикл while повиснет

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

*