STM32 learning experience Eight: Interpretation SystemInit clock system initialization function

Records about the future - easy to read
main elements:
1) understand SystemInit () function and its associated registers involved.
Official data: "the STM32 Chinese Reference Manual V10" Chapter VI reset and clock control RCC
1. Basics:
1.1 SystemInit () function is declared located system_stm32f10x.h header file, the contents of the file in system_stm32f10x.c;
1.2 because the use of STM32F10X_HD, so SystemInit () function partial function does not run.
2. Main register relates to:
Here Insert Picture Description
Here Insert Picture Description
Here Insert Picture Description
Here Insert Picture Description
3. SystemInit () function Interpretation:
Note: The code symbol / / * * ... * * / / actually indicates that the code in the source function, but does not execute.

void SystemInit(void)
{
/*Reset the RCC clock configuration to the default reset state(for debug purpose)*/
/*Set HSI ON bit */
RCC->CR |= (uint32_t)0x00000001;               /*时钟控制寄存器(RCC_CR),内部8MHz振荡器开启*/
/*Reset SW,SWS, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits */
#ifndef STM32F10X_CL
RCC->CFGR &= (uint32_t)0xF8FF0000;             /*因为用STM32F10X_HD,所以运行这一行代码*/
#else
//** RCC->CFGR &= (uint32_t)0xF0FF0000; **//   /*不执行*/
#endif  
/*Reset HSEON, CSSON and PLLON bits */
RCC->CR &= (uint32_t)0xFEF6FFFF;               /*将HSEON, CSSON 和 PLLON置0 */
/*Reset HSEBYP bit */
RCC->CR &= (uint32_t)0xFFFBFFFF;               /* 将HSEBYP置0 */
/*Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits */
RCC->CFGR &=(uint32_t)0xFF80FFFF;              /*将PLLSRC,PLLXTPRE,PLLMUL,USBPRE/OTGFSPRE置0 */
#ifdef STM32F10X_CL
/* Reset PLL2ON and PLL3ON bits */
//**RCC->CR &=(uint32_t)0xEBFFFFFF;**//
/* Disable all interrupts and clear pending bits  */
//**RCC->CIR =0x00FF0000;**//
/* Reset CFGR2 register */
//**RCC->CFGR2 =0x00000000;**//
//**#elif defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)**//
/* Disable all interrupts and clear pending bits  */
//**RCC->CIR =0x009F0000;**//
/* Reset CFGR2 register */
//**RCC->CFGR2 =0x00000000;**//      
#else
/*Disable all interrupts and clear pending bits */
RCC->CIR = 0x009F0000;     /*CIR时钟中断寄存器*/
#endif /*STM32F10X_CL */
//**#if defined (STM32F10X_HD) || (defined STM32F10X_XL) || (defined STM32F10X_HD_VL)**//
  //**#ifdef DATA_IN_ExtSRAM**//
  //**SystemInit_ExtMemCtl();**//
  //**#endif /* DATA_IN_ExtSRAM */
//**#endif **//
/* Configure the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers */
/* Configure the Flash Latency cycles and enable prefetch buffer */
SetSysClock();                       /*重点函数*/
#ifdef VECT_TAB_SRAM
SCB->VTOR = SRAM_BASE |VECT_TAB_OFFSET;
/* Vector Table Relocation in Internal SRAM. */
#else
SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET;
/* Vector Table Relocation in Internal FLASH. */
#endif 
}

4. SetSysClock () function Interpretation:

static void SetSysClock(void)
{
#ifdef SYSCLK_FREQ_HSE
SetSysClockToHSE();
#elif defined SYSCLK_FREQ_24MHz
SetSysClockTo24();
#elif defined SYSCLK_FREQ_36MHz
SetSysClockTo36();
#elif defined SYSCLK_FREQ_48MHz
SetSysClockTo48();
#elif defined SYSCLK_FREQ_56MHz
SetSysClockTo56();  
#elif defined SYSCLK_FREQ_72MHz          
SetSysClockTo72();                        /*重点函数,只执行这一条函数*/
#endif

because:

/*#define SYSCLK_FREQ_HSE    HSE_VALUE */
/*#define SYSCLK_FREQ_24MHz  24000000 */ 
/*#define SYSCLK_FREQ_36MHz  36000000 */
/*#define SYSCLK_FREQ_48MHz  48000000 */
/*#define SYSCLK_FREQ_56MHz  56000000 */
#define SYSCLK_FREQ_72MHz  72000000          /*只有这条激活*/
#endif

5. SetSysClockTo72 () function Interpretation:

static void SetSysClockTo72(void)
{
__IO uint32_t StartUpCounter = 0, HSEStatus = 0;
/*SYSCLK, HCLK, PCLK2 and PCLK1 configuration ------------*/    
/*Enable HSE */    
RCC->CR |= ((uint32_t)RCC_CR_HSEON);                   /*对应#define RCC_CR_HSEON ((uint32_t)0x00010000),将HSEON置1*/
/* Wait till HSE is ready and if Time out is reached exit */
do
{
HSEStatus = RCC->CR & RCC_CR_HSERDY;
/*对应#define RCC_CR_HSERDY ((uint32_t)0x00020000),读取HSERDY值,其值为1时外部振荡器就绪*/
StartUpCounter++;  
} while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); 
/*对应#define HSE_STARTUP_TIMEOUT ((uint16_t)0x0500),当HSEStatus为0时,则没准备就绪,继续循环,只有当HSEStatus为1(即HSERDY值为1),或等于HSE_STARTUP_TIMEOUT(超时)时,跳出循环。*/
if ((RCC->CR & RCC_CR_HSERDY) !=RESET)                /*如果CR值不等于0*/
{
HSEStatus = (uint32_t)0x01;                           /*则,HSEStatus值为1*/
}
else
{
HSEStatus = (uint32_t)0x00;                           /*否则,HSEStatus值为0*/
} 
if (HSEStatus == (uint32_t)0x01)                      /*如果,HSEStatus值为1,即HSE准备就绪*/
{
/*Enable Prefetch Buffer */
FLASH->ACR |= FLASH_ACR_PRFTBE;                   /*对应/#define FLASH_ACR_PRFTBE ((uint8_t)0x10),启用预取缓冲区*/   
/* Flash 2 wait state */
FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY); /*对应#define FLASH_ACR_LATENCY ((uint8_t)0x03),无解释*/ 
FLASH->ACR |=(uint32_t)FLASH_ACR_LATENCY_2;     /*对应#define FLASH_ACR_LATENCY_2 ((uint8_t)0x02),两个等待状态*/    
/*HCLK = SYSCLK */
RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;
/*对应#define RCC_CFGR_HPRE_DIV1 ((uint32_t)0x00000000),即对AHP预分频执行不分频命令*/
/*PCLK2 = HCLK */
RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;
/*对应#define RCC_CFGR_PPRE2_DIV1 ((uint32_t)0x00000000),即对高速APB预分频(APB2)执行不分频命令*/
/*PCLK1 = HCLK/2 */
RCC->CFGR |=(uint32_t)RCC_CFGR_PPRE1_DIV2;
/*对应#define RCC_CFGR_PPRE1_DIV2 ((uint32_t)0x00000400),即对低速APB预分频(APB1)执行2分频命令*/
#ifdefSTM32F10X_CL
/* Configure PLLs ------------*/
/* PLL2 configuration: PLL2CLK = (HSE / 5) * 8 = 40 MHz */
/* PREDIV1 configuration: PREDIV1CLK = PLL2 / 5 = 8 MHz */
//**RCC->CFGR2 &=(uint32_t)~(RCC_CFGR2_PREDIV2 | RCC_CFGR2_PLL2MUL | RCC_CFGR2_PREDIV1 | RCC_CFGR2_PREDIV1SRC);**//
//**RCC->CFGR2|=(uint32_t)(RCC_CFGR2_PREDIV2_DIV5|RCC_CFGR2_PLL2MUL8|RCC_CFGR2_PREDIV1SRC_PLL2|RCC_CFGR2_PREDIV1_DIV5);**//
/* Enable PLL2 */
//**RCC->CR |= RCC_CR_PLL2ON;**//
/* Wait till PLL2 is ready */
//**while((RCC->CR & RCC_CR_PLL2RDY) == 0)**//
//**{**//
//**}**//
/* PLL configuration: PLLCLK = PREDIV1 * 9 = 72 MHz */ 
//**RCC->CFGR &=(uint32_t)~(RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL);**//
//**RCC->CFGR |=(uint32_t)(RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLSRC_PREDIV1|RCC_CFGR_PLLMULL9); **//
#else   
/*  PLL configuration: PLLCLK = HSE * 9 = 72 MHz*/
RCC->CFGR &=(uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE |RCC_CFGR_PLLMULL));
/*对应#define RCC_CFGR_PLLSRC ((uint32_t)0x00010000);#define RCC_CFGR_PLLXTPRE ((uint32_t)0x00020000);#define RCC_CFGR_PLLMULL ((uint32_t)0x003C0000)*/
RCC->CFGR |=(uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL9);
/*对应#define RCC_CFGR_PLLSRC_HSE ((uint32_t)0x00010000);#define RCC_CFGR_PLLMULL9 ((uint32_t)0x001C0000) */
#endif                     /* STM32F10X_CL */
/*Enable PLL */
RCC->CR |= RCC_CR_PLLON;                              /*对应#define RCC_CR_PLLON ((uint32_t)0x01000000)*/
/*Wait till PLL is ready */
while((RCC->CR & RCC_CR_PLLRDY)== 0)                  /*对应#define RCC_CR_PLLRDY ((uint32_t)0x02000000)*/
{
}
/*Select PLL as system clock source */
RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));    /*对应#define RCC_CFGR_SW ((uint32_t)0x00000003)*/
RCC->CFGR |=(uint32_t)RCC_CFGR_SW_PLL;                /*对应#define RCC_CFGR_SW_PLL ((uint32_t)0x00000002)*/  
/*Wait till PLL is used as system clock source */
while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08)/*对应#define RCC_CFGR_SWS ((uint32_t)0x0000000C)*/
{
}
}
else
{
/* If HSE fails to start-up, the application will have wrong clock configuration. User can add here some code to deal with this error */
}
}
#endif

6. SystemInit () function Step Interpretation:
1.1 RCC_CR the Set HSION // 'bit, or operation //
XXXX XXXX XXXX XXXX | XXXX XXXX XXXX XXX1
1.2 RCC_CFGR // the Reset SW, SWS, HPRE, PPRE1, PPRE2, and MCO ADCPRE bits, and operation //
xxxx xxxx xxxx x000 | 0000 0000 0000 0000
1.3 RCC_CR // the Reset HSEON, CSSON and PLLON bits, and arithmetic //
xxxx xxxx xxx0 0xx0 | xxxx xxxx xxxx xxxx
1.4 RCC_CR // the Reset HSEBYP bit, and operation //
x0xx xxxx xxxx xxxx | xxxx xxxx xxxx xxxx
1.5 RCC_CFGR // the Reset PLLSRC, PLLXTPRE, PLLMUL and USBPre / OTGFSPRE bits, and arithmetic //
xxxx xxxx x000 0000 | xxxx xxxx xxxx xxxx
1.6 RCC_CIR // Disable the Clear All interrupts and the Pending bits, = operator //
0000 1001 1111 0000 | 0000 0000 0000 0000
1.7 into SetSysClock (function);
1.8 into SetSysClockTo72 (function);
1.9 provided uint32_t StartUpCounter = 0 __IO, HSEStatus = 0;
1.10 RCC-> CR | = ((uint32_t ) RCC_CR_HSEON);
// RCC_CR_HSEON is 0x00010000, the HSEON // set. 1
XXXX XXXX XXXX XXX1 | XXXX XXXX XXXX XXXX
1.11 HSEStatus = RCC-> CR & RCC_CR_HSERDY;
// RCC_CR_HSERDY as 0x00020000), the value assigned HSEStatus // HSERDY
00x0 0000 0000 0000 | 0000 0000 0000 0000
1.12 // if the HSERDY step read is 1, or timeout, continue to the next step, otherwise, have been circulating on the step //
1.13 ** if ((RCC-> CR & RCC_CR_HSERDY !) = the RESET) **
// If not RCC_CR 0000 0000 0000 0000 | 0000 0000 0000 0000 //
HSEStatus = (uint32_t) 0x01;// then, HSEStatus // value 0x01
the else
HSEStatus = (uint32_t) 0x00; // Otherwise, HSEStatus value of 0x00, i.e. due to timeout is out of step 5.11 // cycle
1.14 IF (HSEStatus == (uint32_t) 0x01) / / 0x01 If HSEStatus value, i.e., the external oscillator is ready, then the following steps are carried //
1.15 // Reiterating, the step runs only HSEStatus value 0x01! //
1.16 FLASH - Play> the ACR | = FLASH_ACR_PRFTBE; // FLASH_ACR_PRFTBE is 0x10), to enable the prefetch buffer //
1.17 ** FLASH - Play> the ACR & = (uint32_t) ((uint32_t) ~ FLASH_ACR_LATENCY); **
// FLASH_ACR_LATENCY 0000 0011 1111 1100 was negated, and thus the operation, the ACR is first cleared xxxx xx00 //
FLASH - Play> the ACR | = (uint32_t) FLASH_ACR_LATENCY_2;
after // FLASH_ACR_LATENCY_2 0000 0010 oR operation, and the ACR change is xxxx xx10, by assignment, i.e., two wait states //
1.18 RCC-> CFGR | = (uint32_t) RCC_CFGR_HPRE_DIV1;
// RCC_CFGR_HPRE_DIV1 to 0x00000000), in fact, had no effect on the original value CFGR //
RCC-> CFGR | = (uint32_t) RCC_CFGR_PPRE2_DIV1;
// RCC_CFGR_PPRE2_DIV1 to 0x00000000), in fact, had no effect on the original value CFGR //
RCC-> CFGR | = ( uint32_t) RCC_CFGR_PPRE1_DIV2;
// RCC_CFGR_PPRE1_DIV2 as 0x00000400), or after the operation, CFGR to XXXX XXXX XXXX XXXX | XXXX XXXX XXXX x1xx //
1.19 RCC-> & CFGR = (uint32_t) ((uint32_t) ~ (RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL) );
// RCC_CFGR_PLLSRC is 0x00010000); RCC_CFGR_PLLXTPRE as 0x00020000); RCC_CFGR_PLLMULL of 0x003C0000), thus followed by three or 0000 0000 0011 1111 | 0000 0000 0000 0000, the negation is 1111 1111 1100 0000 | 1111 1111 1111 1111, and after the operation is a xx00 0000 XXXX XXXX | XXXX XXXX XXXX XXXX //
RCC-> CFGR | = (uint32_t) (RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL9);
// RCC_CFGR_PLLSRC_HSE is 0000 0000 0000 0001 | 0000 0000 0000 0000); RCC_CFGR_PLLMULL9 is 0000 0000 0001 1100 | 0000 0000 0000 0000), or both followed by 0000 0000 0001 1101 | 0000 0000 0000 0000, or after calculation of xxxx xxxx xxx1 11x1 | XXXX XXXX XXXX XXXX //
1.20 RCC-> CR | = RCC_CR_PLLON;
// RCC_CR_PLLON is 0x01000000, XXX1 XXXX XXXX oR operation XXXX | XXXX XXXX XXXX XXXX //
1.21 ** the while ((RCC-> CR & RCC_CR_PLLRDY) = 0 =) **
// RCC_CR_PLLRDY is 0000 0010 0000 0000 | 0000 0000 0000 0000, and 0000 00x0 0000 0000 after calculation | 0000 0000 0000 0000, when x is 0, i.e., the PLL is not locked, 0 == 0, while loop continues, when is 1 x, i.e., the PLL is locked, out of the while loop //
1.22 RCC-> & CFGR = (uint32_t) ((uint32_t) ~ (RCC_CFGR_SW));
// RCC_CFGR_SW is 0x00000003, negated after 1,111,111,111,111,111 | 1111 1111 1111 1100, and xxxx xxxx xxxx after operation xxxx | xxxx xxxx xxxx xx00 //
RCC-> CFGR | = (uint32_t) RCC_CFGR_SW_PLL;
// RCC_CFGR_SW_PLL is 0x00000002, or after calculation xxxx xxxx xxxx xxxx | xxxx xxxx xxxx xx10, i.e., the system clock PLL output //
the while ((RCC-> & CFGR (uint32_t) RCC_CFGR_SWS !) = (uint32_t) 0x08)
// RCC_CFGR_SWS as 0x0000000C, and after calculation of CFGR 0000 0000 0000 0000 | 0000 0000 0000 xx00, when xx is 10, the PLL output SWS display system clock //
1.23 #ifdef VECT_TAB_SRAM
SCB of -> = VTOR the SRAM_BASE | VECT_TAB_OFFSET;
// the Vector Relocation in the Table // Internal SRAM.
#else
SCB-> VTOR = FLASH_BASE | VECT_TAB_OFFSET; // the Vector Relocation in the Table Internal FLASH //.
7. in the startup file startup_stm32f10x_hd.s , there is a compilation of the code:
Reset_Handler the PROC
the EXPORT Reset_Handler [The WEAK]
IMPORT in __main
IMPORT SystemInit
the LDRR0, = SystemInit
BLX R0
LDR R0, = __ main
BX R0
ENDP
reason the assembly code instructions, when the system is reset, it will first run SystemInit function, and then run the main function, which is why the main function is generally not SystemInit function.
Knowledge points :
1) The system clock reference may be better understood SystemInit function block diagram, reference STM32 learning experience VII: Interpretation STM32 clock and a system block diagram related functions ;
2) related to the familiar parameters register.

Published 24 original articles · won praise 2 · Views 4125

Guess you like

Origin blog.csdn.net/Leisure_ksj/article/details/105255484