STM32 experiencia de aprendizaje Ocho: la función de inicialización del sistema de reloj SystemInit Interpretación

Registros sobre el futuro - fácil de leer
elementos principales:
función 1) entender SystemInit () y sus registros asociados implicados.
Los datos oficiales: "el Manual de Referencia STM32 chino V10" Capítulo VI de reposición y control de reloj RCC
1. Conceptos básicos:
la función SystemInit 1.1 () se declara el archivo de cabecera system_stm32f10x.h ubicado, el contenido del archivo en system_stm32f10x.c;
1.2 debido a que el uso de STM32F10X_HD, por lo SystemInit () de función parcial no se ejecuta.
2. registro principal se refiere a:
Aquí Insertar imagen Descripción
Aquí Insertar imagen Descripción
Aquí Insertar imagen Descripción
Aquí Insertar imagen Descripción
3. SystemInit () la función Interpretación:
Nota: El símbolo de código / / * * ... * * / / realidad indica que el código de la función de origen, pero no se ejecuta.

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 () Función de Interpretación:

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

porque:

/*#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 () Función de Interpretación:

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 () Interpretación función Paso:
1.1 RCC_CR el Set HSION // 'bits, o la operación //
XXXX XXXX XXXX XXXX | XXXX XXXX XXXX XXX1
1,2 RCC_CFGR // el RESET SW, bits de SWS, HPRE, PPRE1, PPRE2, y MCO ADCPRE, y la operación //
xxxx xxxx xxxx X000 | 0,000 0,000 0,000 0,000
1,3 RCC_CR // Reset HSEON, CSSON y PLLON los bits, y la aritmética //
xxxx xxxx xxx0 0xx0 | xxxx xxxx xxxx xxxx
1,4 RCC_CR // Reset bit HSEBYP, y la operación //
x0xx xxxx xxxx xxxx | xxxx xxxx xxxx xxxx
1,5 RCC_CFGR // reset PLLSRC, PLLXTPRE, PLLMUL y USBPre / OTGFSPRE trozos, y la aritmética //
xxxx xxxx x000 0000 | xxxx xxxx xxxx xxxx
1.6 RCC_CIR // Desactivar las Borrar todos interrupciones y los bits pendientes, = operador //
0000 1001 1111 0000 | 0000 0000 0000 0000
1,7 en SetSysClock (función);
1,8 en SetSysClockTo72 (función);
1.9 proporcionado uint32_t StartUpCounter = 0 __IO, HSEStatus = 0;
1,10 RCC-> CR | = ((uint32_t ) RCC_CR_HSEON);
// RCC_CR_HSEON es 0x00010000, el conjunto HSEON // 1.
XXXX XXXX XXXX XXX1 | XXXX XXXX XXXX XXXX
1,11 HSEStatus = RCC-> CR & RCC_CR_HSERDY;
// RCC_CR_HSERDY como 0x00020000), el valor asignado HSEStatus // HSERDY
00x0 0000 0000 0000 | 0000 0000 0000 0000
1,12 // si el paso de lectura HSERDY es 1, o tiempo de espera, continúe con el siguiente paso, de lo contrario, han estado circulando en el escalón //
1,13 ** if ((RCC-> CR y RCC_CR_HSERDY !) = RESET) **
// Si no RCC_CR 0000 0000 0000 0000 | 0000 0000 0000 0000 //
HSEStatus = (uint32_t) 0x01;// entonces, HSEStatus // valor 0x01
el otro
HSEStatus = (uint32_t) 0x00; // De lo contrario, el valor HSEStatus de 0x00, es decir, debido a tiempo de espera es de paso 5.11 // ciclo de
1,14 IF (HSEStatus == (uint32_t) 0x01) / / 0x01 Si HSEStatus valor, es decir, el oscilador externo está listo, a continuación, los siguientes pasos se llevan a //
1,15 // Reiterando, el paso se ejecuta sólo valor HSEStatus 0x01! //
1,16 FLASH - Juego> ACR | = FLASH_ACR_PRFTBE; // FLASH_ACR_PRFTBE es 0x10), para permitir que el buffer de captación previa //
1,17 ** FLASH - Juego> ACR & = (uint32_t) ((uint32_t) ~ FLASH_ACR_LATENCY); **
// FLASH_ACR_LATENCY 0000 0011 1111 1100 fue negada, y por lo tanto la operación, el ACR se borra primera xxxx xx00 //
FLASH - Juego> ACR | = (uint32_t) FLASH_ACR_LATENCY_2;
después // FLASH_ACR_LATENCY_2 0000 0010 o la operación, y el cambio del ACR es xxxx xx10, por asignación, es decir, dos estados de espera //
1,18 RCC-> CFGR | = (uint32_t) RCC_CFGR_HPRE_DIV1;
// RCC_CFGR_HPRE_DIV1 a 0x00000000), de hecho, no tuvo ningún efecto sobre la CFGR valor original //
RCC-> CFGR | = (uint32_t) RCC_CFGR_PPRE2_DIV1;
// RCC_CFGR_PPRE2_DIV1 a 0x00000000), de hecho, no tuvo ningún efecto sobre la CFGR valor original //
RCC-> CFGR | = ( uint32_t) RCC_CFGR_PPRE1_DIV2;
// RCC_CFGR_PPRE1_DIV2 como 0x00000400), o después de la operación, CFGR a 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 es 0x00010000); RCC_CFGR_PLLXTPRE como 0x00020000); RCC_CFGR_PLLMULL de 0x003C0000), de este modo, seguido de tres o 0000 0000 0011 1111 | 0000 0000 0000 0000, la negación es 1111 1111 1100 0000 | 1111 1111 1111 1111, y después de la operación es un xx00 0000 XXXX XXXX | XXXX XXXX XXXX XXXX //
RCC-> CFGR | = (uint32_t) (RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL9);
// RCC_CFGR_PLLSRC_HSE es 0000 0000 0000 0001 | 0000 0000 0000 0000); RCC_CFGR_PLLMULL9 es 0000 0000 0001 1100 | 0000 0000 0000 0000), o ambos seguido por 0,000 0,000 0,001 1,101 | 0,000 0,000 0,000 0,000, o después del cálculo de xxxx xxxx xxx1 11x1 | XXXX XXXX XXXX XXXX //
1,20 RCC-> CR | = RCC_CR_PLLON;
// RCC_CR_PLLON es 0x01000000, XXX1 XXXX XXXX XXXX o la operación | XXXX XXXX XXXX XXXX //
1,21 ** el tiempo ((RCC-> CR & RCC_CR_PLLRDY) = 0 =) **
// RCC_CR_PLLRDY es 0000 0010 0000 0000 | 0000 0000 0000 0000, y 0000 00x0 0000 0000 después del cálculo | 0.000 0.000 0.000 0.000, cuando x es 0, es decir, el PLL no está bloqueado, 0 == 0, mientras que bucle continúa, cuando es de 1 x, es decir, el PLL está bloqueado, fuera del bucle while //
1,22 RCC-> & CFGR = (uint32_t) ((uint32_t) ~ (RCC_CFGR_SW));
// RCC_CFGR_SW es 0x00000003, negada después 1.111.111.111.111.111 | 1111 1111 1111 1100, y xxxx xxxx xxxx xxxx después de la operación | xxxx xxxx xxxx xx00 //
RCC-> CFGR | = (uint32_t) RCC_CFGR_SW_PLL;
// RCC_CFGR_SW_PLL es 0x00000002, o después del cálculo xxxx xxxx xxxx xxxx | xxxx xxxx xxxx xx10, es decir, la salida PLL reloj del sistema //
el tiempo ((RCC-> & CFGR (uint32_t) RCC_CFGR_SWS !) = (uint32_t) 0x08)
// RCC_CFGR_SWS como 0x0000000C, y después de cálculo de CFGR 0000 0000 0000 0000 | 0000 0000 0000 xx00, cuando xx es 10, el reloj de salida sistema de visualización SWS PLL //
1,23 #ifdef VECT_TAB_SRAM
SCB de -> = VTOR la SRAM_BASE | VECT_TAB_OFFSET;
// la Reubicación del vector en la Tabla SRAM // interna.
#else
SCB-> VTOR = FLASH_BASE | VECT_TAB_OFFSET; // la Reubicación del vector en la Tabla flash interna //.
7. en los startup_stm32f10x_hd.s fichero de inicio , hay una compilación del código:
Reset_Handler el PROC
el EXPORTACIÓN Reset_Handler [la débil]
importación en __main
IMPORTACIÓN SystemInit
la LDRR0, = SystemInit
BLX R0
LDR R0, = __ principal
BX R0
ENDP
razón las instrucciones de código de montaje, cuando el sistema se reinicia, se ejecuta por primera vez la función SystemInit, a continuación, ejecutar la función principal, que es la razón por la función principal por lo general no es función SystemInit.
puntos de conocimiento :
1) La referencia de reloj de sistema se puede entender mejor función SystemInit diagrama de bloques, la referencia STM32 experiencia VII aprendizaje: Interpretación reloj STM32 y un bloque de sistema de funciones relacionadas con el diagrama ;
2) relacionados con los parámetros familiares registran.

Publicado 24 artículos originales · ganado elogios 2 · Vistas 4125

Supongo que te gusta

Origin blog.csdn.net/Leisure_ksj/article/details/105255484
Recomendado
Clasificación