ARM Cortex-M4: клок #1

Итак, запускаем среду разработки Atmel Studio, выбираем контроллер ATSAM4Cxx_0 и программатор в опции device и tool соответственно.

 

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

Тактовый сигнал жизненно необходим для любого контроллера, он задает точный ритм работы, благодаря которому все команды и процессы выполняются синхронно. Первое, что нужно сделать при разработке программы для Cortex-M4, да и вообще для ARM — это настроить систему тактирования.

Она управляется PMC — контроллером питания, как ни странно.

Ashampoo_Snap_2014.06.05_12h45m45s_022_

Пока, я полагаю, мало что понятно. Начну с того, что вся периферия и сам ЦП работают от главного MaterClock-а, при этом мы можем выбрать что тактировать, а что — нет. В архитектуре ARM такая логика: нет clock-а — нет проблем! Поэтому при подачи питания большая часть периферии не работает.

Источником для MasterClock может являться  резонатор/генератор, а его частота еще до MaterClock-а всячески преобразовывается системой тактирования, что позволяет нам увеличивать или уменьшать частоту всего МК программно.  Рассмотрим первый блок:

Ashampoo_Snap_2014.06.05_12h45m45s_025432_

Возможных путей преобразования сигнала с генераторов не мало.
Переключатели просто выбирают источник частоты, а с PLL или ФАПЧ дела обстоят интереснее. У каждого блока PLL есть два регистра: MUL и DIV. MUL — задает коэффициент умножения частоты на входе, а DIV ее последующее деление. То есть, формула выходной частоты блока будет такой: fвых = (fвх * MUL)/DIV Естественно, MUL и DIV не должны равняться нулю, иначе PLL блок просто отключится.

В итоге мы получаем сразу четыре разных clock-а:

  • SLCK — всегда ~32KHz
  • MAINCK — выбирается по-умолчанию после сброса, от 4 до 20MHz
  • PLLACK — выходная частота с первого блока умножения, от 1 до 8MHz возможно.
  • PLLBCK — выходная частота со второго блока, от 1 до 240MHz возможно, но контроллер не будет работать выше 120MHz.

Они поступают во вторую часть:

Ashampoo_Snap_2014.06.05_12h45m45s_02632_

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

Не маловажным является контроллер периферии, функция которого отключение тактирования того или иного модуля.

1
2
PMC->PMC_PCER0 = НомерПериферийногоУстройства; //Включить тактирование
PMC->PMC_PCDR0 = НомерПериферийногоУстройства; //Выключить тактирование

Настройка

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

Для начала разблокируем регистры:

1
PMC->PMC_WPMR = 0x504D43; //Очень черная магия

Следующий шаг — определиться с рабочей частотой, к примеру, мы хотим аж 120MHz. Как ее получить? Используем часовой кварц и два PLL блока (так советует документация): f = (f32KHz * 250) * 15.

Ashampoo_Snap_2014.06.05_12h45m4532fd45s_022_

В коде это будет описано так:

1
2
3
4
5
6
7
8
9
PMC->CKGR_MOR = CKGR_MOR_MOSCXTEN; //Используем внешний кристалл
 
PMC->CKGR_PLLAR = CKGR_PLLAR_PLLACOUNT(0) | CKGR_PLLAR_PLLAEN(0); //PLLA: Сброс
PMC->CKGR_PLLAR = CKGR_PLLAR_MULA(249) | CKGR_PLLAR_PLLAEN(1); //PLLA: Умножить на 250
PMC->CKGR_PLLBR = CKGR_PLLBR_PLLBCOUNT(0); //PLLB: Сброс
PMC->CKGR_PLLBR = CKGR_PLLBR_MULB(14) | CKGR_PLLBR_DIVB(1) | CKGR_PLLBR_SRCB_PLLA_IN_PLLB; //PLLB: Умножить на 15, делить на 1, источник — PLLA.
 
PMC->PMC_MCKR = PMC_PCK_CSS_PLLB_CLK | PMC_PCK_PRES_CLK_1; //MasterClock: Источник — PLLB, Делить на 1.
SystemCoreClockUpdate(); //Обновим главную переменную, используемую для задержек и прочих.

Последняя строчка обновляет переменную SystemCoreClock (uint32_t), в которой будет десятичное значение текущей частоты. Однако, я заметил некоторую странность ее поведения, поэтому, если имеются проблемы, то присваивайте вручную:

1
SystemCoreClock = 120000000;

Но у вас, скорее всего, ничего не заработает. :) Мы забыли очень важную вещь: тактирование flash памяти происходит по-иному: вместо частоты у нее есть параметр — задержка, ее нужно изменить.

1
system_init_flash(120000000);

Ставьте эту строчку до инициализации системы тактирования.

Проверка

Для проверки системы тактирования вы можете использовать PCKпрограммируемый выводной контроллер частоты. Он имеет несколько выходных пинов, на которые мы можем вывести нашу тактовую частоту. Возьмем PCK0 — это PB13.

1
2
3
4
5
6
7
8
9
10
11
12
PMC->PMC_PCER0 = PMC_PCER0_PID12; //Включили тактирование PB порта
//Настройка порта. Об этом в другой статье.
PIOB->PIO_IDR = PIO_IDR_P13;
PIOB->PIO_OER = PIO_OER_P13;
last = PIOB->PIO_ABCDSR[0];
PIOB->PIO_ABCDSR[0] &= (~PIO_ABCDSR_P13 & last);
last = PIOB->PIO_ABCDSR[1];
PIOB->PIO_ABCDSR[1] &= (~PIO_ABCDSR_P13 & last);
PIOB->PIO_PDR = PIO_PDR_P13;
//Настройка PCK
PMC->PMC_PCK[0] = PMC_PCK_CSS_MCK | PMC_PCK_PRES_CLK_1; //Выбираем наш MasterClock и предделитель = 1
PMC->PMC_SCER = PMC_SCER_PCK0; //Разрешить тактирование регистра PCK0

Теперь смотрим на наш пин осциллографом:

pic_165_1

Если ваш осциллограф не поддерживает такую частоту, то увеличьте предделитель PCK.


Все части

Вы можите оставить комментарий, или поставить трэкбек со своего сайта.

Написать комментарий

XHTML: Вы можете использовать эти теги: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

Bug Report
Локализовано: шаблоны Wordpress