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