Konfigurace hodin pro ST32F103C8

Jan Waclawek konfera na efton.sk
Středa Duben 15 22:06:50 CEST 2015


>Takze az na tu blbu adresu registra RCC_CR to bolo naklikane dobre. 
>Tieto 3 riadky (v tomto poradi) stacia 


Hm, cakal by som, ze to po studenom boote (zapnuti z vypnuteho zdroja)
nepojde - podla RM0008 sa PLL nema zapnut pred stabilizaciou zdroja jeho
hodin a povodny zdroj systemovych hodin (HSI) sa nema vypnut pred
stabilizaciou novych (PLL). 

Je mozne, ze to je osetrene v hardwari, ale tiez je mozne, ze to za
nejakych okolnosti fungovat nebude.

> (aj ked osobne by som to rozdelil  na viac krokov)

To, to. 

A tiez nemam rad magicke hodnoty. Toto je moja varianta pre nakopnutie
'F407 na maximalnych 168MHz:


#define XTAL_MHz   12  // MHz
#define SYSCLK_MHz 168 // MHz

int main(void) {


  RCC->CR |= ((uint32_t)RCC_CR_HSEON);  // enable HSE
  while((RCC->CR & RCC_CR_HSERDY) == 0);  // wait until up

  // before firing up PLL, one word of caution: the VOS bit in PWR_CR
register must be 1 for fSYS>144MHz
  // that's the reset value so there's no need to change it here (VOS=0
brings some 10% reduction in power consumption between 30MHz-144MHz)
  // if we'd need to change it, the power module's clock would have to be
fired up, too - see the STM-supplied "systemInit" code

  RCC->CFGR |=    RCC_CFGR_HPRE_DIV1    // AHB prescaler set to 1 -> AHB
clock = 168MHz
                | RCC_CFGR_PPRE1_DIV4   // APB1 prescaler set to 4 -> APB1
clock = 42MHz (required to be < 42MHz)
                | RCC_CFGR_PPRE2_DIV2;  // APB2 prescaler set to 2 -> APB2
clock = 84MHz (required to be < 84MHz)

  RCC->PLLCFGR =    ( XTAL_MHz  * RCC_PLLCFGR_PLLM_0)     // M = XTAL
divider - the PLL needs 1MHz to 2MHz at its input
                 |  ((SYSCLK_MHz * 2) * RCC_PLLCFGR_PLLN_0)    // N = PLL
multiplier (feedback divider) - the VCO's output needs to fall between
64MHz and 432MHz
                 |  (0 * RCC_PLLCFGR_PLLP_0)      // P = divider for SYSCLK
- 0 = /2, 1 = /4, 2 = /6, 3 = /8
                 |  (7 * RCC_PLLCFGR_PLLQ_0)      // Q = divider for USB
(and SDIO and RNG), should result in 48MHz but that's unattainable with
this setup - we won't use it anyway - for SDIO and RNG it should be below
48MHz
                 |  (RCC_PLLCFGR_PLLSRC_HSE);     // PLL source is HSE

  RCC->CR |= RCC_CR_PLLON;  // fire up PLL
  while((RCC->CR & RCC_CR_PLLRDY) == 0);  // and wait until up

  FLASH->ACR =  0
                | FLASH_ACR_ICEN          // meantime, configure flash for
maximum performance - enable both caches
                | FLASH_ACR_DCEN
                | FLASH_ACR_PRFTEN        // errata says this is
"unavailable" for A-revision devices - should we selectively disable this
through reading DBGMCU_IDCODE?
                | FLASH_ACR_LATENCY_5WS;  // for VCC>2.7V and FSYS>144MHz,
5 waitstate is appropriate

  RCC->CFGR = (RCC->CFGR & (~(RCC_CFGR_SW))) | RCC_CFGR_SW_PLL;  // switch
clock source to PLL
  while ((RCC->CFGR & RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL);  // wait until
switches
  // and that's it.



Musel som si dodefinovat hodnoty pre bitove polia (napr.
FLASH_ACR_LATENCY_5WS), A TYMTO ZNOVA APELUJEM NA PRITOMNYCH Z ST, ABY TO
DO STANDARDNYCH DEVICE HEADEROV DODEFINOVALI.

Pochopitelne sa to da "zautomatizovat" pre rozne cielove systemove
frekvencie, ako to robia v tom "standardnom" ARMom/CMSIS-om vynutenom
startupe, ale podla mna sa to zbytocne zneprehladni a na druhej strane by
clovek mal vediet co robi.

wek





Další informace o konferenci Hw-list