STM32 experiência de aprendizagem Oito: função de inicialização do sistema relógio SystemInit Interpretação

Registros sobre o futuro - fácil de ler
elementos principais:
a função 1) entender SystemInit () e seus registros associados envolvidos.
Os dados oficiais: "o Manual STM32 chinês Referência V10" Capítulo VI reinicialização e controle relógio RCC
1. Basics:
função 1.1 SystemInit () é declarado localizado arquivo de cabeçalho system_stm32f10x.h, o conteúdo do arquivo em system_stm32f10x.c;
1.2 porque o uso de STM32F10X_HD, assim SystemInit () função função parcial não é executado.
2. registo principal relaciona-se com:
Aqui Insert Picture Descrição
Aqui Insert Picture Descrição
Aqui Insert Picture Descrição
Aqui Insert Picture Descrição
3. SystemInit () função Interpretação:
Nota: O símbolo de código / / * * ... * * / / realmente indica que o código na função de origem, mas não executa.

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 () função Interpretação:

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 () função Interpretação:

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 () Interpretação função Passo:
1,1 RCC_CR o Conjunto HSION // 'bits, ou operação //
XXXX XXXX XXXX XXXX | XXXX XXXX XXXX XXX1
1,2 RCC_CFGR // o SW RESET, bits de SWS, HPRÉ, PPRE1, PPRE2, e MCO ADCPRE, e operação //
xxxx xxxx xxxx x000 | 0000 0000 0000 0000
1.3 RCC_CR // reset HSEON, CSSON e PLLON pedaços e aritmética //
xxxx xxxx xxx0 0xx0 | xxxx xxxx xxxx xxxx
1,4 RCC_CR // reset HSEBYP bit e operação //
x0xx xxxx xxxx xxxx | xxxx xxxx xxxx xxxx
1,5 RCC_CFGR // reset PLLSRC, PLLXTPRE, PLLMUL e USBPre / OTGFSPRE pedaços e aritmética //
xxxx xxxx x000 0000 | xxxx xxxx xxxx xxxx
1,6 RCC_CIR // Desabilitar as Limpar Todas as interrupções e os bits pendentes, = operador //
0000 1001 1111 0000 | 0000 0000 0000 0000
1,7 em SetSysClock (função);
1,8 em SetSysClockTo72 (função);
1.9 fornecida uint32_t StartUpCounter = 0 __IO, HSEStatus = 0;
1,10 Rcc-> CR | = ((uint32_t ) RCC_CR_HSEON);
// RCC_CR_HSEON é 0x00010000, o HSEON // conjunto 1.
XXXX XXXX XXXX XXX1 | XXXX XXXX XXXX XXXX
1,11 HSEStatus = Rcc-> CR & RCC_CR_HSERDY;
// RCC_CR_HSERDY como 0x00020000), o valor atribuído HSEStatus // HSERDY
00x0 0000 0000 0000 | 0000 0000 0000 0000
1,12 // se a leitura etapa HSERDY é 1, ou tempo limite, continue para a próxima etapa, caso contrário, têm circulado na etapa //
1,13 ** if ((Rcc-> CR & RCC_CR_HSERDY !) = RESET) **
// Se não RCC_CR 0000 0000 0000 0000 | 0000 0000 0000 0000 //
HSEStatus = (uint32_t) 0x01;// então, HSEStatus // valor 0x01
o outro
HSEStatus = (uint32_t) 0x00; // Caso contrário, o valor HSEStatus de 0x00, isto é, devido ao tempo limite é de 5,11 // passo ciclo
1,14 IF (HSEStatus == (uint32_t) 0x01) / / 0x01 Se HSEStatus valor, ou seja, o oscilador externo está pronto, em seguida, as seguintes etapas são realizadas //
1,15 // Reiterando, o passo é executado somente valor HSEStatus 0x01! //
1,16 FLASH - Play> ACR | = FLASH_ACR_PRFTBE; // FLASH_ACR_PRFTBE é 0x10), para permitir que o tampão de pré-busca //
1,17 ** FLASH - Play> ACR & = (uint32_t) ((uint32_t) ~ FLASH_ACR_LATENCY); **
// FLASH_ACR_LATENCY 0000 0011 1111 1100 foi negada, e, portanto, a operação, a ACR é primeiro limpo xxxx xx00 //
FLASH - Play> ACR | = (uint32_t) FLASH_ACR_LATENCY_2;
depois // FLASH_ACR_LATENCY_2 0000 0010 ou operação, ea mudança ACR é xxxx xx10, por cessão, ou seja, dois estados de espera //
1,18 Rcc-> CFGR | = (uint32_t) RCC_CFGR_HPRE_DIV1;
// RCC_CFGR_HPRE_DIV1 para 0x00000000), na verdade, não teve efeito sobre o CFGR valor original //
Rcc-> CFGR | = (uint32_t) RCC_CFGR_PPRE2_DIV1;
// RCC_CFGR_PPRE2_DIV1 para 0x00000000), na verdade, não teve efeito sobre o CFGR valor original //
Rcc-> CFGR | = ( uint32_t) RCC_CFGR_PPRE1_DIV2;
// RCC_CFGR_PPRE1_DIV2 como 0x00000400), ou após a operação, CFGR para 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 é 0x00010000); RCC_CFGR_PLLXTPRE como 0x00020000); RCC_CFGR_PLLMULL de 0x003C0000), assim seguido de três ou 0000 0000 0011 1111 | 0000 0000 0000 0000, a negação é 1111 1111 1100 0000 | 1111 1111 1111 1111, e após a operação é um xx00 0000 XXXX XXXX | XXXX XXXX XXXX XXXX //
Rcc-> CFGR | = (uint32_t) (RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL9);
// RCC_CFGR_PLLSRC_HSE é 0000 0000 0000 0001 | 0000 0000 0000 0000); RCC_CFGR_PLLMULL9 é 0000 0000 0001 1100 | 0000 0000 0000 0000), ou ambos seguidos por 0000 0000 0001 1101 | 0000 0000 0000 0000, ou após o cálculo de xxxx xxxx xxx1 11x1 | XXXX XXXX XXXX XXXX //
1,20 Rcc-> CR | = RCC_CR_PLLON;
// RCC_CR_PLLON é 0x01000000, XXX1 XXXX XXXX ou operação XXXX | XXXX XXXX XXXX XXXX //
1,21 ** o while ((Rcc-> CR & RCC_CR_PLLRDY) = 0 =) **
// RCC_CR_PLLRDY é 0000 0010 0000 0000 | 0000 0000 0000 0000, e 0000 00x0 0000 0000 após o cálculo | 0000 0000 0000 0000, quando X é 0, isto é, a PLL não está bloqueado, 0 == 0, while continua, quando é 1 x, isto é, o PLL é bloqueado, para fora do circuito enquanto //
1,22 Rcc-> & CFGR = (uint32_t) ((uint32_t) ~ (RCC_CFGR_SW));
// RCC_CFGR_SW é 0x00000003, negada após 1.111.111.111.111.111 | 1111 1111 1111 1100, e xxxx xxxx xxxx xxxx após operação | xxxx xxxx xxxx xx00 //
Rcc-> CFGR | = (uint32_t) RCC_CFGR_SW_PLL;
// RCC_CFGR_SW_PLL é 0x00000002, ou após o cálculo xxxx xxxx xxxx xxxx | xxxx xxxx xxxx xx10, isto é, a PLL saída de relógio do sistema //
o while ((Rcc-> & CFGR (uint32_t) RCC_CFGR_SWS !) = (uint32_t) 0x08)
// RCC_CFGR_SWS como 0x0000000C, e após o cálculo de CFGR 0000 0000 0000 0000 | 0000 0000 0000 xx00, quando xx é 10, o relógio de saída do sistema de exibição SWS PLL //
1,23 #ifdef VECT_TAB_SRAM
SCB de -> = Vtor o SRAM_BASE | VECT_TAB_OFFSET;
// o Vector Relocation na Tabela SRAM // interno.
#else
SCB-> Vtor = FLASH_BASE | VECT_TAB_OFFSET; // o Vector Relocation na Tabela flash interna //.
7. nas startup_stm32f10x_hd.s arquivo de inicialização , não é uma compilação do código:
Reset_Handler o PROC
a EXPORT Reset_Handler [o fraco]
IMPORT em __main
IMPORT SystemInit
do LDRR0, = SystemInit
BLX R0
LDR R0, = __ principal
BX R0
ENDP
razão as instruções de código de montagem, quando o sistema é reiniciado, ele primeiro vai executar a função SystemInit, e depois executar a função principal, que é por isso que a função principal não é geralmente SystemInit função.
pontos de conhecimento :
1) A referência relógio do sistema pode ser melhor compreendida a função SystemInit diagrama de blocos, referência STM32 experiência VII aprender: Interpretação relógio STM32 e um bloco de sistema relacionado diagrama funções ;
2) relacionadas com os parâmetros familiares registo.

Publicado 24 artigos originais · ganhou elogios 2 · Vistas 4125

Acho que você gosta

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