Изучаем ARM. Контроллер питания SAM3S. Как настроить тактовую частоту

Контроллер питания SAM3S

Микроконтроллер без тактового сигнала так же нежизнеспособен, как и человек без сердечного ритма. Поэтому стоит начать знакомство с микроконтроллером SAM3S, разобравшись с его системой тактирования. 

Всеми тактовыми сигналами в микроконтроллере SAM3S заведует контроллер питания (Power Management Controller или PMC). В состав контролера питания входит блок тактового генератора и различные узлы, управляющие выбором тактового сигнала, коэффициентами деления, разрешением или запрещением тактирования периферии микроконтроллера.

Рассмотрим тактовый генератор. Он имеет в своем составе:

• встроенный низкочастотный RC генератор с частотой 32768 Гц
• низкочастотный RC генератор с внешним резонатором
• встроенный высокочастотный RC генератор с частотами 4, 8, 12 МГц
• высокочастотный генератор с внешним резонатором на 3 - 20 МГц
• два программируемых PLL модуля

Тактовый генератор SAM3S


Для подключения внешних резонаторов используются выводы XIN32, XOUT32 и XIN, XOUT. Также на выводы XIN32 и XIN можно подавать тактовые сигналы с внешнего генератора, но для этого нужно отключать внутренние генераторы (так называемый bypass режим). 


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

Модули PLLA и PLLB позволяют умножать входящий тактовый сигнал на коэффициент (MUL + 1) и делить его на коэффициент DIV. MUL может принимать значение от 1 до 36. При 0 модуль PLL неактивен. DIV может быть в диапазоне от 1 до 255. При 0 на выходе PLL модуля нулевой логический уровень. Минимальная входная частота для модулей PLL равна 3.5 МГц, максимальная 20 МГц.

Теперь посмотрим на полную блок схему контроллера питания.

 

Контроллер питания ARM SAM3S


С блока тактового генератора выходят 4 тактовых сигнала, каждый из которых может быть выбран для тактирования процессора, периферии, USB модуля или вывода на внешние устройства. 


Самый основной узел PMC - это Master Clock Controller. От него тактовый сигнал идет на процессор и периферию. Есть несколько периферийных модулей, которые тактируются постоянно, но большая часть периферии может отключаться. Перед работой с такой периферией нужно сначала разрешить ее тактирование, для этого служит блок Peripherals Clock Controller.

Programmable Clock Controller позволяет выводить тактовый сигнал на специальные выводы микроконтроллера SAM3S. Для этого нужно разрешить эту функцию в контроллере питания и контроллере портов ввода-вывода.

Все настройки контроллера питания задаются в его регистрах. Я не буду их разбирать, потому что это займет очень много времени, и отошлю вас к даташиту.

Настройка тактовой частоты

Теперь вы имеете общее представление о контроллере питания. Разберемся как настроить тактовую частоту микроконтроллера SAM3S в коде.

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

Первый шаг - создаем пустой проект для микроконтроллера SAM3S4B, используя шаблон user board. Как создать проект в Atmel Studio подробно описано ранее.

С помощью ASF Wizard подключаем к проекту следующие библиотеки:

• System Clock Control - сервис для настройки тактовой частоты
• Delay routines - сервис реализующий программные задержки
• PMC-Power Management Controller - драйвер контроллера питания
• PIO-Parallel Input/Output Controller - драйвер контроллера вводы-вывода
• WDT-Watchdog Timer - драйвер сторожевого таймера

После добавления библиотек они отобразятся в проводнике в разделах services и drivers.


Если пробежаться в проводнике по папкам, то можно найти файл user_board.h. Он предназначен для хранения различных макроопределений, имеющих отношение к пользовательской плате. В данном случае к Karma-SAM3S. Для использования сервиса System Clock Control нужно добавить в файл user_board.h следующие определения:


//внешний низкочастотный кварцевый резонатор
#define BOARD_FREQ_SLCK_XTAL (32768U)

// внешний низкочастотный генератор
#define BOARD_FREQ_SLCK_BYPASS (32768U)

// внешний высокочастотный кварцевый резонатор
#define BOARD_FREQ_MAINCK_XTAL (12000000U)

// внешний высокочастотный генератор
#define BOARD_FREQ_MAINCK_BYPASS (12000000U)

// время запуска генератора
#define BOARD_OSC_STARTUP_US 500000


На плате Karma-SAM3S используется только внешний высокочастотный кварцевый резонатор, но правила требуют определять в коде все константы. (Закомментированный в этом файле код можно оставить как есть.)

Настройку тактовой частоты выполняет функция sysclk_init(), а конфигурация задается в файле conf_clock.h. Открыв его, мы увидим много закомментированных макроопределений.

Чтобы задать максимальную частоту тактирования для микроконтроллера SAM3S4B нужно:

• выбрать в качестве системного тактового сигнала - сигнал с выхода PLLA

#define CONFIG_SYSCLK_SOURCE       SYSCLK_SRC_PLLACK


• задать в качестве источника тактового сигнала для PLLA - генератор с внешним резонатором

#define CONFIG_PLL0_SOURCE       PLL_SRC_MAINCK_XTAL


• установить коэффициенты умножения и деления для PLLA

#define CONFIG_PLL0_MUL       32
#define CONFIG_PLL0_DIV        3


• установить коэффициент деления главного контроллера тактового сигнала

#define CONFIG_SYSCLK_PRES       SYSCLK_PRES_2

В итоге тактовая частота микроконтроллера будет равна ((12 МГЦ * 32)/3)/2 = 64 МГц. А код файла conf_clock.h будет выглядеть так.

// ===== System Clock (MCK) Source Options
//#define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_SLCK_RC
//#define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_SLCK_XTAL
//#define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_SLCK_BYPASS
//#define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_MAINCK_4M_RC
//#define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_MAINCK_8M_RC
//#define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_MAINCK_12M_RC
//#define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_MAINCK_XTAL
//#define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_MAINCK_BYPASS
#define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLLACK
//#define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLLBCK

// ===== System Clock (MCK) Prescaler Options (Fmck = Fsys / (SYSCLK_PRES))
//#define CONFIG_SYSCLK_PRES SYSCLK_PRES_1
#define CONFIG_SYSCLK_PRES SYSCLK_PRES_2
//#define CONFIG_SYSCLK_PRES SYSCLK_PRES_4
//#define CONFIG_SYSCLK_PRES SYSCLK_PRES_8
//#define CONFIG_SYSCLK_PRES SYSCLK_PRES_16
//#define CONFIG_SYSCLK_PRES SYSCLK_PRES_32
//#define CONFIG_SYSCLK_PRES SYSCLK_PRES_64
//#define CONFIG_SYSCLK_PRES SYSCLK_PRES_3

// ===== PLL0 (A) Options (Fpll = (Fclk * PLL_mul) / PLL_div)
// Use mul and div effective values here.
#define CONFIG_PLL0_SOURCE PLL_SRC_MAINCK_XTAL
#define CONFIG_PLL0_MUL 32
#define CONFIG_PLL0_DIV 3


В качестве источника тактового сигнала для PLLA также можно также выбрать встроенный RC генератор. Кликните на надписи PLL_SRC_MAINCK_XTAL правой кнопкой мышки и выберете в меню пункт Goto Implementation. Откроется файл pll.h, в котором вы увидите все возможные варианты выбора.

"Визуально" конфигурация контроллера питания будет выглядеть так.

Конфигурация контроллера питания SAM3S


Когда конфигурация настроена, мы просто прописываем в начале функции main() вызов функции sysclk_init(). После ее выполнения микроконтроллер будет тактироваться сигналом с частотой 64 МГц.

Тестовый проект

Ну и небольшой тестовый код для проверки изложенной теории. Если вы добавите его в созданный только что проект, скомпилируете и загрузите прошивку в Karma-SAM3S, то увидите, как на плате с частотой 1 Гц моргает светодиод.

#include <asf.h>

#define LED1 PIO_PA17

int main (void)
{ 
   /*настраиваем частоту тактирования*/
   sysclk_init();
 
   /*запрещаем сторожевой таймер*/
   wdt_disable(WDT);

   /*разрешаем тактирование контроллера ввода-вывода*/
   pmc_enable_periph_clk(ID_PIOA);

   /*настраиваем вывод LED1 на выход*/
   pio_set_output(PIOA, LED1, LOW, DISABLE, DISABLE);

   while(1){
      /*моргаем светодиодом*/
      delay_ms(500); 
      pio_set(PIOA, LED1);
      delay_ms(500);
      pio_clear(PIOA,LED1); 
   }
}


Функция программной задержки delay_ms связана с функцией sysclk_init(). Поэтому она "знает" на какой частоте работает микроконтроллер и реализует соответствующий код. Если вы заглянете в файл delay.h, то найдете там дополнительные функции - delay_s(), delay_us(). Также там есть функция инициализации - delay_init(), но она нужна, когда тактовая микроконтроллера частота настраивается "вручную".

Если под рукой есть осциллограф, можно визуально убедиться в правильности настройки тактовой частоты, подключив выход PLLA модуля к специальным выводам микроконтроллера SAM3S (смотри блок схему контроллера питания). Например, к выводу PA6.

Добавьте перед циклом while представленный ниже код и на выводе PA6 будет будет тактовый сигнал с частотой 128 МГц/64 = 2 МГц (128 МГц - это тактовый сигнал с выхода PLLA, а 64 - предделитель Programmable Clock Controller`a). Можно вывести и 128 МГц, если ваш осциллограф позволяет наблюдать такие сигналы.

 /*подключаем выход PLLA к выводу PA6/PCK0
 и устанавливаем предделитель - 64 */
 pmc_switch_pck_to_pllack(PMC_PCK_0 , PMC_PCK_PRES_CLK_64);
 
 /*разрешаем вывод тактовой частоты на PCK0*/
 pmc_enable_pck(PMC_PCK_0);
 
 /*разрешаем периферийную функцию на выводе PA6*/
 pio_set_peripheral(PIOA, PIO_TYPE_PIO_PERIPH_B, PIO_PA6);


Поиграв с настройками файла conf_clock.h, можно убедиться в том, что все работает как надо. Светодиод при любых настройках будет моргать с частотой 1 Гц, а частота на выводе PA6 будет меняться согласно настройкам.

На этом все. Продолжение следует. На очереди порты ввода-вывода, а потом что-нибудь про прерывания. Как видите, благодаря мощной среде разработки и готовым библиотекам, ARM от Atmel имеет низкий порог вхождения. Разобраться в нем по силам даже новичку.

Ссылки

Плата для изучения микроконтроллера SAM3S
Даташит на микроконтроллер SAM3S
Clock-1-AS6.rar - тестовый проект

Другие материалы в этой категории: « Karma-SAM3S. Как сделать проект в Atmel Studio

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

При добавлении в комментарий Си кода, заключайте его между тегами [code] [/code]. Иначе он будет отображаться некорректно.


Защитный код
Обновить