Микроконтроллеры

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » Микроконтроллеры » STM32 » Система тактирования


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

Сообщений 1 страница 15 из 15

1

Система тактирования для F4 на примере F4 дискавери .

Сперва определимся с терминами и что, где искать в документации.

RM0090 Rev13. Ищем Clock tree.

http://s0.uploads.ru/Fn57B.png

Рассмотрим подробнее путь прохождения и трансформации тактовой частоты на примере варианта HSE+PLL.

http://s5.uploads.ru/dZs02.png

Читаем параграф 7.2 Clocks, а именно

All peripheral clocks are derived from the system clock (SYSCLK) except for:
• The USB OTG FS clock (48 MHz), the random analog generator (RNG) clock
(≤48 MHz) and the SDIO clock (≤ 48 MHz) which are coming from a specific output of
PLL (PLL48CLK)


Вся периферия тактируется от SYSCLK за исключением USB OTG FS,RNG,SDIO.
Источником тактовой для них служит PLL48CLK.

http://s0.uploads.ru/0iHFj.png

http://s3.uploads.ru/ki182.png

Читаем о PLL48 и о PLL вообще:

7.2.3 PLL configuration
The STM32F4xx devices feature two PLLs:
• A main PLL (PLL) clocked by the HSE or HSI oscillator and featuring two different
output clocks:
– The first output is used to generate the high speed system clock (up to 168 MHz)
– The second output is used to generate the clock for the USB OTG FS (48 MHz),
the random analog generator (≤48 MHz) and the SDIO (≤ 48 MHz).


Основной PLL тактируется от HSE или HSI и имеет два различных выхода тактовой:
- Первый для системной тактовой (вплоть до 168МГц)
-Второй , как выше и писано, для USB OTG FS,RNG,SDIO

Since the main-PLL configuration parameters cannot be changed once PLL is enabled, it is
recommended to configure PLL before enabling it (selection of the HSI or HSE oscillator as
PLL clock source, and configuration of division factors M, N, P, and Q).

Параметры PLL не могут быть изменены если PLL включена,
рекомендуется конфигурировать PLL до его включения( выбор HSI или HSE как источников
тактирование PLL и конфигурации делителей M, N, P, и Q)

Далее, идем в параграф 7.3.1 RCC clock control register (RCC_CR)

Здесь читаем о битах включения PLL и его готовности :

Bit 25 PLLRDY: Main PLL (PLL) clock ready flag
Set by hardware to indicate that PLL is locked.
0: PLL unlocked
1: PLL locked
Bit 24 PLLON: Main PLL (PLL) enable
Set and cleared by software to enable PLL.
Cleared by hardware when entering Stop or Standby mode. This bit cannot be reset if PLL
clock is used as the system clock.
0: PLL OFF
1: PLL ON

http://s1.uploads.ru/Tk8aJ.png
На рисунке /M соответствует PLLM, N- PLLN, VCO- VCO, P-PLLP,Q-PLLQ.

Идем в параграф 7.3.2 RCC PLL configuration register (RCC_PLLCFGR)

This register is used to configure the PLL clock outputs according to the formulas:
• f(VCO clock) = f(PLL clock input) × (PLLN / PLLM)
• f(PLL general clock output) = f(VCO clock) / PLLP
• f(USB OTG FS, SDIO, RNG clock output) = f(VCO clock) / PLLQ

Сей регистр служит для конфигурации выхлопа тактовой PLL исходя из формулы.

f(VCO clock) = f(PLL clock input) × (PLLN / PLLM)
Здесь определяется внутренняя тактовая PLL.
Где
VCO выход внутреннего делителя.
PLL clock input вход PLL
PLLN множитель VCO
PLLM делитель тактовой от HSI или HSE

http://sg.uploads.ru/K8TU0.png


Далее делитель для PLL48CK, для USB OTG FS, SDIO, RNG
• f(USB OTG FS, SDIO, RNG clock output) = f(VCO clock) / PLLQ

Ну и делитель для системной тактовой
• f(PLL general clock output) = f(VCO clock) / PLLP

Читаем о PLLQ

Bits 27:24 PLLQ: Main PLL (PLL) division factor for USB OTG FS, SDIO and random number generator
clocks
Set and cleared by software to control the frequency of USB OTG FS clock, the random
number generator clock and the SDIO clock. These bits should be written only if PLL is
disabled.
Caution: The USB OTG FS requires a 48 MHz clock to work correctly. The SDIO and the
random number generator need a frequency lower than or equal to 48 MHz to work
correctly.
USB OTG FS clock frequency = VCO frequency / PLLQ with 2 ≤PLLQ ≤15
0000: PLLQ = 0, wrong configuration
0001: PLLQ = 1, wrong configuration
0010: PLLQ = 2
0011: PLLQ = 3
0100: PLLQ = 4
...
1111: PLLQ = 15


Главное

Caution: The USB OTG FS requires a 48 MHz clock to work correctly.
Внимание: USB OTG FS требует 48МГц для корректной работы.

Читаем о выборе источника тактирования PLL
Цитата:

Bit 22 PLLSRC: Main PLL(PLL) and audio PLL (PLLI2S) entry clock source
Set and cleared by software to select PLL and PLLI2S clock source. This bit can be written
only when PLL and PLLI2S are disabled.
0: HSI clock selected as PLL and PLLI2S clock entry
1: HSE oscillator clock selected as PLL and PLLI2S clock entry


Теперь у нас есть все что необходимо для конфигурирации PLL.

1) Определяемся с чего бум тактировать - либо HSI (16МГц ) либо HSE( смотрим на кварц)

Вычисляем делители PLL исходя из выше озвученных частот, того что для USB нужно 48МГц
и желаемом системной частоты .
2) Кофигурируем PLL - делители и источник .
3) Ждем готовности PLL.
















Система тактирования F4 на примере STM32F4 дискавери

Откроем  startup_stm32f407xx.s .
    При старте выполнение кода начинается  с вектора сброса  Reset_Handler.
    Найдем  эту секцию:

Код:
   ; Reset handler
Reset_Handler    PROC
                 EXPORT  Reset_Handler             [WEAK]
        IMPORT  SystemInit
        IMPORT  __main

                 LDR     R0, =SystemInit      <=====  
                 BLX     R0
                 LDR     R0, =__main
                 BX      R0
                 ENDP

Как видим до перехода на main вызывается функция SystemInit.
Находится она в system_stm32f4xx.c и содержит начальную инициализацию тактовой .

Исключим из компиляции файл  system_stm32f4xx.c и добавим свой clock_init.c
  который будет содержать ту же функцию SystemInit  но уже с нашим вариантом инициализации тактовой .

Итак при старте системы мы имеем следующее :

Система тактируется от HSI (16МГц)
Латентность флеш на минимуме

Основные  манипуляции, что нужно произвести для перехода на максимальную частоту тактирования  -168МГц от HSE (8МГц):

-Включить HSE и дождаться его готовности
-Настроить делители шин AHB,APB1и APB2
-Сконфигурировать PLL  включить PLL и дождаться готовности
-Настроить Flash prefetch, instruction cache, data cache и wait state
-Выбрать PLL источником тактирования системы и дождаться переключения

Напомню что частоты тактирования  модулей вычисляется исходя из формул

             PLL_VCO = ([HSE_VALUE or HSI_VALUE] / PLL_M) * PLL_N
             SYSCLK = PLL_VCO / PLL_P   
             USB OTG FS, SDIO and RNG Clock =  PLL_VCO / PLLQ 

Читаем о
  PLL_M

Bits 5:0 PLLM: Division factor for the main PLL (PLL) and audio PLL (PLLI2S) input clock
Set and cleared by software to divide the PLL and PLLI2S input clock before the VCO.
These bits can be written only when the PLL and PLLI2S are disabled.
Caution: The software has to set these bits correctly to ensure that the VCO input frequency
ranges from 1 to 2 MHz. It is recommended to select a frequency of 2 MHz to limit
PLL jitter.

Основное — на вход VCO  можно подавать частоту в диапазоне 1-2МГц . Рекомендуется 2МГц для ограничения джиттера PLL.

PLL_N

Bits 14:6 PLLN: Main PLL (PLL) multiplication factor for VCO
Set and cleared by software to control the multiplication factor of the VCO. These bits can
be written only when PLL is disabled. Only half-word and word accesses are allowed to
write these bits.
Caution: The software has to set these bits correctly to ensure that the VCO output
frequency is between 100 and 432 MHz.
VCO output frequency = VCO input frequency × PLLN with 50 ≤ PLLN ≤ 432


  Частота на выходе VCO  может быть в диапазоне 100-432 МГц .
PLL_P

Bits 17:16 PLLP: Main PLL (PLL) division factor for main system clock
Set and cleared by software to control the frequency of the general PLL output clock. These
bits can be written only if PLL is disabled.
Caution: The software has to set these bits correctly not to exceed 168 MHz on this domain.
PLL output clock frequency = VCO frequency / PLLP with PLLP = 2, 4, 6, or 8
00: PLLP = 2
01: PLLP = 4
10: PLLP = 6
11: PLLP = 8


  Как видим минимальный делитель PLL_P может быть только 2.
   
И исходя из вышеозвученных ограничений определяем необходимые параметры
                       множителей/делителей

  Кварц F4 дискавери 8МГц  - соответственно  PLL_N  выбираем 4

SYSCLK = PLL_VCO / PLL_P
  Sysclk должна быть 168МГц , минимальное значение PLL_P 2 -соответсвенно частота на    выходеVCO будет 168МГц *2 = 336МГц и множитель PLL_N  равен 168 :
PLL_N = PLL_VCO / ([HSE_VALUE or HSI_VALUE] / PLL_M)
PLL_N = 336МГц / (8МГц / 4)

Ну и PLL_Q

PLLQ =  PLL_VCO /USB OTG FS, SDIO and RNG Clock
PLLQ = 336МГц/48МГц
PLLQ=7

http://sg.uploads.ru/tALCm.png

В итоге :

Код:
 #define PLL_M  4
 #define PLL_N  168

 #define PLL_P   2
 #define PLL_Q   7

Кофигурируем систему тактирование.

Включаем HSE и дожидаемся его готовности.

Код:
RCC->CR|= RCC_CR_HSEON;   
	  while (!(RCC->CR &RCC_CR_HSERDY)){};

Определяем делители шин.

Код:
RCC->CFGR |=RCC_CFGR_HPRE_DIV1|RCC_CFGR_PPRE2_DIV2|RCC_CFGR_PPRE1_DIV4;

на AHB 168МГц – предделитель 0;

Bits 15:13 PPRE2: APB high-speed prescaler (APB2)
Set and cleared by software to control APB high-speed clock division factor.
Caution: The software has to set these bits correctly not to exceed 84 MHz on this domain.
The clocks are divided with the new prescaler factor from 1 to 16 AHB cycles after
PPRE2 write.
0xx: AHB clock not divided
100: AHB clock divided by 2
101: AHB clock divided by 4
110: AHB clock divided by 8
111: AHB clock divided by 16
Bits 12:10 PPRE1: APB Low speed prescaler (APB1)
Set and cleared by software to control APB low-speed clock division factor.
Caution: The software has to set these bits correctly not to exceed 42 MHz on this domain.
The clocks are divided with the new prescaler factor from 1 to 16 AHB cycles after
PPRE1 write.
0xx: AHB clock not divided
100: AHB clock divided by 2
101: AHB clock divided by 4
110: AHB clock divided by 8
111: AHB clock divided by 16


  APB2=SYSCLK/2 = 168МГц/2 = 84МГц
APB1=SYSCLK/4 = 168МГц/4 = 42МГц

Заносим конфигурацию PLL.

Код:
RCC->PLLCFGR = PLL_M|(PLL_N<<6)|(((PLL_P>>1)-1)<<16)|RCC_PLLCFGR_PLLSRC_HSE|(PLL_Q<<24);

Включаем PLL и дожидаемся готовности PLL.

Код:
	RCC->CR |= RCC_CR_PLLON;
	while (!(RCC->CR &RCC_CR_PLLRDY)){};

Настраиваем Flash prefetch, instruction cache, data cache и wait state :
см таблицу на стр. 80 RM0090

http://sa.uploads.ru/YxnMF.png

Код:
FLASH->ACR|=FLASH_ACR_ICEN | FLASH_ACR_DCEN | FLASH_ACR_LATENCY_5WS | FLASH_ACR_PRFTEN;

Переключаем системное татирование на PLL.

Код:
	RCC->CFGR &= ~RCC_CFGR_SW;
  RCC->CFGR |= RCC_CFGR_SW_PLL;

И дожидаемся этого переключения.

Код:
 while (!(RCC->CFGR & RCC_CFGR_SWS ) ){};

Для контроля выводим SYSCLK на MCO2 (PC9), частота на MCO2 =  SYSCLK/5:

Код:
	RCC->AHB1ENR|=RCC_AHB1ENR_GPIOCEN;
	GPIOC->MODER&=~GPIO_MODER_MODE9;
	GPIOC->MODER|=GPIO_MODER_MODE9_1;
	GPIOC->OSPEEDR|=GPIO_OSPEEDER_OSPEEDR9;
	RCC->CFGR|=RCC_CFGR_MCO2PRE;

2

Код:
#define PLL_M  4
#define PLL_N  168
#define PLL_P   2
#define PLL_Q   7

void SystemInit(void)
{
  /* FPU settings ------------------------------------------------------------*/
  #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
    SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2));  /* set CP10 and CP11 Full Access */
  #endif
  
	RCC->AHB1ENR|=RCC_AHB1ENR_GPIOCEN;
	GPIOC->MODER&=~GPIO_MODER_MODE9;
	GPIOC->MODER|=GPIO_MODER_MODE9_1;
	GPIOC->OSPEEDR|=GPIO_OSPEEDER_OSPEEDR9;
	RCC->CFGR|=RCC_CFGR_MCO2PRE;
	
	
	RCC->CR|= RCC_CR_HSEON;
	while (!(RCC->CR &RCC_CR_HSERDY)){};
	
    
	RCC->CFGR |=	RCC_CFGR_HPRE_DIV1 | RCC_CFGR_PPRE2_DIV2 |RCC_CFGR_PPRE1_DIV4;
	RCC->PLLCFGR = PLL_M|(PLL_N<<6)|(((PLL_P>>1)-1)<<16)|RCC_PLLCFGR_PLLSRC_HSE|(PLL_Q<<24);
	
	RCC->CR |= RCC_CR_PLLON;
	while (!(RCC->CR &RCC_CR_PLLRDY)){};
	
  FLASH->ACR|=FLASH_ACR_ICEN | FLASH_ACR_DCEN | FLASH_ACR_LATENCY_5WS | FLASH_ACR_PRFTEN;
    
	RCC->CFGR &= ~RCC_CFGR_SW;
  RCC->CFGR |= RCC_CFGR_SW_PLL;

   
  while (!(RCC->CFGR & RCC_CFGR_SWS ) ){};
   

  
}

3

Система тактирования для F0 , на примере  F042x, F072x

Открываем даташиты на чипы и RM0091

Так же находим Clock tree .

http://se.uploads.ru/q4hGo.png

http://s4.uploads.ru/fbkhH.png

http://s4.uploads.ru/lkQBO.png

Обратите внимание, в свежих даташитах наконец-то корректно обозначены сущности .
На сером фоне, белым текстом.

http://s45.radikal.ru/i108/1703/95/d3ca17bc39b8.png

http://i026.radikal.ru/1703/60/08f18dee7fc9.png

4

Для F072 и F042  тактирование системы от PLL , PLL от HSI.
  Sysclk 48MHz .

Код:
  void SystemInit (void)
    	{     
    	if ((RCC->CFGR & RCC_CFGR_SWS) == RCC_CFGR_SWS_PLL)  
    	{ 
    	 RCC->CFGR &= (uint32_t) (~RCC_CFGR_SW);
    	 while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_HSI) 
    	 {
    	
    	 }
    	}
    	
    	RCC->CR &= (uint32_t)(~RCC_CR_PLLON);
    	while((RCC->CR & RCC_CR_PLLRDY) != 0) {};
    	FLASH->ACR = FLASH_ACR_PRFTBE | FLASH_ACR_LATENCY;
    	RCC->CFGR|=RCC_CFGR_PLLSRC_0;
    	RCC->CFGR = (RCC->CFGR & (~RCC_CFGR_PLLMUL)) | (RCC_CFGR_PLLMUL6); 
    	
    	RCC->CR |= RCC_CR_PLLON; 
    	while((RCC->CR & RCC_CR_PLLRDY) == 0){};
    	
    	RCC->CFGR |= (uint32_t) (RCC_CFGR_SW_PLL);
    	while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL) {};
    	
    	}
    	

  Здесь собственно и разбирать-то нечего.
Вначале выясняем -если система тактируется от PLL , переключаемся на тактирование от HSI и дожидаемся этого переключения(зачем?)
Выключаем PLL, ждем разлочки PLL.
Настраиваем PLL, латентность flash.
Включаем PLL, дожидаемся готовности PLL.
Переключаем тактирование системы на PLL и дожидаемся этого переключения.

5

Для F072 и F042  тактирование системы от PLL , PLL от HSE.
  Sysclk 48MHz

Код:
void SystemInit (void)
    	{     
    	if ((RCC->CFGR & RCC_CFGR_SWS) == RCC_CFGR_SWS_PLL)  
    	{ 
    	 RCC->CFGR &= (uint32_t) (~RCC_CFGR_SW);
    	 while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_HSI) 
    	 {
    	
    	 }
    	}
    	RCC->CR |= ((uint32_t)RCC_CR_HSEON);
          while((RCC->CR & RCC_CR_HSERDY) == 0)    
          {          
          }
        

    	RCC->CR &= (uint32_t)(~RCC_CR_PLLON);
    	while((RCC->CR & RCC_CR_PLLRDY) != 0) {};
    	FLASH->ACR = FLASH_ACR_PRFTBE | FLASH_ACR_LATENCY;
    	RCC->CFGR|=RCC_CFGR_PLLSRC_1;
    	RCC->CFGR = (RCC->CFGR & (~RCC_CFGR_PLLMUL)) | (RCC_CFGR_PLLMUL6); 
    	
    	RCC->CR |= RCC_CR_PLLON; 
    	while((RCC->CR & RCC_CR_PLLRDY) == 0){};
    	
    	RCC->CFGR |= (uint32_t) (RCC_CFGR_SW_PLL);
    	while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL) {};
    	
    	}
    	

6

Разъясните,пожалуйста.
По умолчанию,регистр CFGR сброшен.
http://s3.uploads.ru/t/1UmzY.jpg
Но Вы(и не только,это встречается и в примерах от СТМ) некоторые биты сбрасываете:
RCC->CFGR &= ~RCC_CFGR_SW;
В чём причина таких действий?

7

Например потому, что  инит тактовой не только при сбросе может быть, а и на лету ...

8

Перестраховка?

9

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

10

Спасибо.

11

Подскажите, есть ли какое то красивое решение определения sysclock? В смысле измерить надо, исходя из того что мы не знаем ничего о источнике тактового сигнала. Вывести на MCO sysclock, подключить к входу счетчика(таймера). Но это требует внешних цепей :) провод, но он нужен. а можно ли как то по "SISTEMTIMER" определить? его делитель известен. тогда не надо внешних цепей, но как? алгоритм какой?

12

домовой Зачем тебе это надо, чтобы устройство работало от любого кварцевого резонатора?

13

MasterElectric написал(а):

домовой Зачем тебе это надо, чтобы устройство работало от любого кварцевого резонатора?

Ну что то в этом духе. Не моя "тайна" зачем это надо. Предположим что HSI поплыл у меня, и надо точно (насколько это возможно) подправить калибровочную часть. Может получится так, что доступа к плате нет, а SWD выведен. :) ну где то так или около того.

14

возможно.
  \brief  Structure type to access the System Timer (SysTick).
*/
typedef struct
{
  __IOM uint32_t CTRL;                   /*!< Offset: 0x000 (R/W)  SysTick Control and Status Register */
  __IOM uint32_t LOAD;                   /*!< Offset: 0x004 (R/W)  SysTick Reload Value Register */
  __IOM uint32_t VAL;                    /*!< Offset: 0x008 (R/W)  SysTick Current Value Register */
  __IM  uint32_t CALIB;                  /*!< Offset: 0x00C (R/ )  SysTick Calibration Register */
} SysTick_Type;

http://infocenter.arm.com/help/index.js … ieigh.html

Отредактировано домовой (2017-09-06 20:56:35)

15

Там константа
Я не понял, что ты хочешь - точно измерить или грубо оценить, тактирование от HSE или от HSI ?


Вы здесь » Микроконтроллеры » STM32 » Система тактирования