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

Первое что стоит сделать в нашем устройстве — настроить систему тактирования, дабы каждый периферийный блок мог работать корректно. Её обзор был сделан в разделе «Микроконтроллер под микроскопом»). Мы не станем разбирать каждый регистр модуля RCC (Reset and Clock Control), т.к. это сильно отвлечёт от более интересных задач, работы с периферией. Код для настройки будет предоставлен как есть, по завершению курса имеет смысл вернуться к этому разделу и разобраться с остальными регистрами самостоятельно.

В устройстве не предусмотрено внешнего генератора, а значит по умолчанию МК запускается от RC-цепочки и работает на частоте 8 МГц. Этого не достаточно, чтобы корректно работать с датчиком температуры, поэтому частоту нужно увеличить используя PLL, скажем, до 64 МГц.

К слову, 64 МГц довольно высокая частота для реализации часов, но т.к. часы не единственная функция, ваша фантазия не ограничена, а оптимальность написанного вами кода не гарантирована, то остановимся на этом значении.

Алгоритм переключения на PLL следующий:

  1. сброс регистров RCC;
  2. запуск высокочастотного встроенного источника HSI (плюс ожидание выхода в рабочий режим);
  3. настройка и запуск PLL (плюс ожидание выхода в рабочий режим);
  4. настройка и запуск буфера flash-памяти (задержки);
  5. установка предделителей шин (APB1, APB2, AHB);
  6. переключение SYSCLK на PLL (плюс ожидание выхода в рабочий режим);
  7. обновление переменной SystemCoreClock.

При настройке предделителей шин, нужно помнить о том, что не все они могут работать на той же частоте SYSCLK, так APB1 может работать максимум на 36 МГц. Вернитесь в раздел «Микроконтроллер под микроскопом» и рассмотрите диаграмму внимательно.

Ниже приведён код для SPL (для других библиотек обратитесь к репозиторию на github).

Скопируйте данный код в файл utils.c и объявите прототип в utils.h. При необходимости изменить частоту, вам нужно лишь поменять множитель.

Если у вас имеется осциллограф или логический анализатор, то вы можете вывести тактовый сигнал на ножку MCO. При помощи приведённого ниже кода вы можете посмотреть частоту SYSCLK или PLL/2.

Подцепите крокодил к разъёму USB (он подключён к земле), а щуп приложите на медный пяточок (JP1) рядом с МК. Обратите внимание,что максимальная частота, которую способна выдавать ножка равняется 50 МГц, т.е. при максимальной частоте вы увидите шум. Меняйте умножители PLL и посмотрите как меняется сигнал.

Систему тактирования удобно настраивать в STM32CubeMX.

Вернёмся к понятию «регистр». По сути это просто ячейка памяти в которую можно записывать значения. В зависимости от состояния ячеек он активируют или деактивируют некоторую функциональность в системе. Блоком RCC отвечает за тактирование, следовательно через него можно включать или отключать тактирование портов ввода/вывода.

Звучит не сложно, но... усложним и провернём финт ушами. Это поможет вам осознать глубину происходящего. Откройте Reference Manual и найдите в оглавлении пункт «3.3 Memory map». В этой таблице записаны адреса периферийных блоков, нас интересует пункт «Reset and clock control RCC» (модуль системы тактирования).

rcc memory map

Таблица из Reference Manual, Table 3. Register boundary addresses

Он имеет адрес 0x40021000.

Снова перейдите к оглавлению и в «7 Low-, medium-, high- and XL-density reset and clock control (RCC)» перейдите к пункту «7.3.7 APB2 peripheral clock enable register (RCC_APB2ENR)».

apb2enr

Описание регистра APB2ENR из Reference Manual, 7.3.7 APB2 peripheral clock enable register (RCC_APB2ENR)

Данный регистр позволяет включать и отключать тактирование блоков периферии: портов ввода/вывода, SPI, USART и т.д. Записав 1 в четвёртую позицию включается тактирование порта B, и наоборот, записав туда 0, тактирование будет убрано.

В строке «Address» у казано не абсолютное значение, а смещение относительно блока RCC, т.е. адрес регистра 0x40021000 +0x18 = 0x40021018. Записав 1 на место четвёртого бита можно включить тактирование порта B. Как это сделать? Очень просто!

Но, конечно же, никто так код не пишет (21 век, как-никак). Для каждой периферии заведена структура (CMSIS, stm32f10x.h), в которой хранятся переменные, связанные с соответствующими регистрами. В нашем случае это структура RCC. 0x00000008 писать долго, проще использовать битовую операцию смещения:

Такой стиль очень плох. Почему? Допустим, вы передали кому-то код (или еще проще, сами сели за этот проект спустя некоторое время), и для того, чтобы человек понял, что вы конкретно включили этой строчкой кода, ему потребуется залезть в документацию и посмотреть, за что отвечает третий (с нуля) бит в этом регистре. Неудобно, не правда ли? Можно написать комментарий, а можно сделать так, чтобы код говорил сам за себя. Если вы снова откроете stm32f10x.h, то сможете найти макросы масок для всех случаев жизни.

Так намного лучше. Самое время перейти к порта ввода/вывода.

Код урока можно найти на github: CMSIS.


Назад | Оглавление | Дальше