STM32 학습 경험 여덟 : 해석 SystemInit 클럭 시스템 초기화 함수

- 미래에 대한 기록 쉽게 읽을
: 주요 요소를
1) SystemInit 이해 () 함수 및 관련 레지스터가있었습니다.
공식 데이터 : "는 STM32 중국어 참조 서 V10"제 VI 리셋 클럭 제어 RCC
1. 기초 :
1.1 SystemInit () 함수가 위치한 system_stm32f10x.h 헤더 파일 선언, system_stm32f10x.c의 파일의 내용;
1.2 인해 STM32F10X_HD의 사용 그래서 SystemInit () 함수 부분적인 기능은 실행되지 않습니다.
2. 주요 레지스터에 관한
그림 삽입 설명 여기
그림 삽입 설명 여기
그림 삽입 설명 여기
그림 삽입 설명 여기
3 SystemInit () 함수 해석 :
참고 : 코드 심볼 / / * * .. * * / / 실제로 소스 함수의 코드가 있지만 실행되지 않는 것을 나타낸다.

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 () 함수 해석 :

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

때문에 :

/*#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 () 함수 해석 :

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 () 함수의 스텝 해석 :
1.1 RCC_CR 설정 HSION // '비트 또는 동작 //
XXXX XXXX XXXX XXXX | XXXX XXXX XXXX XXX1
1.2 RCC_CFGR // 리셋 SW, SWS, HPRE, PPRE1, PPRE2 및 MCO ADCPRE 비트 운전 //
XXXX XXXX XXXX X000 | 0000 0000 0000 0000
1.3 RCC_CR // 리셋 HSEON, CSSON 및 PLLON 비트 산술 //
XXXX XXXX xxx0 0xx0 | XXXX XXXX XXXX XXXX
1.4 RCC_CR // 리셋 HSEBYP 비트 및 동작 //
x0xx XXXX XXXX XXXX | XXXX XXXX XXXX XXXX
1.5 RCC_CFGR // 재설정 PLLSRC, PLLXTPRE, PLLMUL 및 USBPre / OTGFSPRE 비트 산술 //
XXXX XXXX X000 0000 | XXXX XXXX XXXX XXXX
1.6 RCC_CIR // 안 지우기 모든 인터럽트 보류 비트, = 연산자 //
0,000 1,001 1,111 0,000 | 0000 0000 0000 0000
1.7 SetSysClock (기능)으로,
1.8 SetSysClockTo72 (기능)으로,
1.9 StartUpCounter __IO = 0, = 0 HSEStatus uint32_t 제공;
1.10 RCC-> CR | = ((uint32_t ) RCC_CR_HSEON)
// RCC_CR_HSEON가 0x00010000의 HSEON // 세트 1.
XXXX XXXX XXXX XXX1 | XXXX XXXX XXXX XXXX
1.11 HSEStatus = RCC-> CR 및 RCC_CR_HSERDY;
0x00020000로서 // RCC_CR_HSERDY) 값을 할당 HSEStatus // HSERDY
0000 0000 0000 00x0 | 0000 0000 0000 0000
1.12 HSERDY 단계 읽기 1, 또는 타임 아웃의 경우, 단계 //에 순환되고, 그렇지 않으면 다음 단계를 계속 //
1.13 ** 경우 ((RCC-> CR & RCC_CR_HSERDY !)) 초기화를 = **
0000 0000 0000 // 그렇지 않으면 RCC_CR 0000 | 0000 0000 0000 0000 //
HSEStatus = (uint32_t) 0x01로;// 그리고, HSEStatus // 값 0x01로
다른
HSEStatus = (uint32_t) × 00; 인해 타임 아웃 시간 × 00, 즉의 // 그렇지 HSEStatus 값은 단계 벗어난주기 // 5.11
1.14 IF (HSEStatus == (uint32_t)하는 0x01) / HSEStatus 값, 즉, 외부 발진기가 준비한다면 /하는 0x01, 다음 단계가 수행된다 //
1.15 // 되풀이 공정은 HSEStatus 값 0x01로 실행! //
1.16 플래시 - 플레이>는 ACR | = FLASH_ACR_PRFTBE; // FLASH_ACR_PRFTBE는 프리 페치 버퍼 // 수 있도록,)은 0x10입니다
1.17 ** 플래시 - 재생>은 ACR &는 = (uint32_t) ((uint32_t) ~ FLASH_ACR_LATENCY) **
// FLASH_ACR_LATENCY 0,011 1,111 1,100 0,000이 부정하고, 따라서 동작은 ACR 먼저 XXXX xx00 // 클리어
FLASH - 플레이>는 ACR | = (uint32_t) FLASH_ACR_LATENCY_2;
// FLASH_ACR_LATENCY_2 0000 0010 OR 연산 및 ACR 변경 후 인 XXXX xx10 대입하여, 즉, 두 개의 대기 상태 //
1.18 RCC-> CFGR | = (uint32_t) RCC_CFGR_HPRE_DIV1;
을 0x00000000에 // RCC_CFGR_HPRE_DIV1이) 사실, 원래 값의 CFGR에 아무런 영향을 미치지 않았다 //
RCC-> CFGR | = (uint32_t) RCC_CFGR_PPRE2_DIV1;
을 0x00000000에 // RCC_CFGR_PPRE2_DIV1), 사실, 원래 값의 CFGR에 아무런 영향을 미치지 않았다 //
RCC-> CFGR | = ( uint32_t) RCC_CFGR_PPRE1_DIV2,
0x00000400으로 같은 // RCC_CFGR_PPRE1_DIV2), 또는 수술 후, CFGR 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) )
0x00020000로서 RCC_CFGR_PLLXTPRE); // RCC_CFGR_PLLSRC)는 0x00010000이고 | 0000 0000 0000 0x003C0000의 RCC_CFGR_PLLMULL), 따라서 세 개 0,000 0,011 1,111 0,000이어서 0000, 부정 1111 1111 1100 0000 | 1,111 1,111 1,111 1,111, 및 동작은 xx00 0000 XXXX XXXX 후 | XXXX XXXX XXXX XXXX //
RCC-> CFGR | = (uint32_t) (RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL9);
0000 0000 0000 | // RCC_CFGR_PLLSRC_HSE 0000 0000 0000 0001 ) 0000; RCC_CFGR_PLLMULL9는 0000 0000 0001 1100 | 0000 0000 0000 0000), 또는 둘 모두는 0000 0001 1101 0000 다음 | 0000 0000 0000 0000 또는 XXXX XXXX XXX1 계산 후 11x1 | XXXX XXXX XXXX XXXX //
1.20 RCC-> CR | = RCC_CR_PLLON;
// RCC_CR_PLLON는 0x01000000이고, XXX1 XXXX XXXX XXXX 논리합 | XXXX XXXX XXXX XXXX //
1.21 ** 그동안 ((RCC-> CR 및 RCC_CR_PLLRDY) = 0 =) **
0000 0000 0000 | // RCC_CR_PLLRDY 0000 0010 0000 0000 0000, x는, 즉, PLL이 고정되지 않는 0 인 경우 반복하면서, 0000 0000 0000 0000 0 == 0 | 계산 한 후 0000 00x0 0000 0000 While 루프 //에서, 즉, PLL이 로크되어, 1 개이면, 계속
1.22 ; RCC-> & CFGR = (uint32_t) ((uint32_t) ~ (RCC_CFGR_SW))
// RCC_CFGR_SW는 0x00000003이고 1,111,111,111,111,111 후에 무효화 | 1111 1111 1100 1111 및 XXXX XXXX XXXX 조작 XXXX 후 | XXXX XXXX XXXX xx00 //
RCC-> CFGR | = (uint32_t) RCC_CFGR_SW_PLL;
// RCC_CFGR_SW_PLL가 0x00000002, 또는 계산 후 XXXX XXXX XXXX XXXX | XXXX XXXX XXXX xx10, 즉, 시스템 클록 PLL 출력 //
그동안 ((RCC-> & CFGR (uint32_t) RCC_CFGR_SWS !) = (uint32_t)을 0x08)
// RCC_CFGR_SWS 0x0000000C 등, 0000 0000 0000 CFGR 0000의 계산 후 | 0000 0000 0000 xx00, XX는 (10), PLL 출력 SWS 디스플레이 시스템 클럭 // 때
1.23 VECT_TAB_SRAM #ifdef와
의 SCB -> = VTOR SRAM_BASE | VECT_TAB_OFFSET;
표 // 내부 SRAM에서 // Vector의 재배치.
#else
SCB-> VTOR = FLASH_BASE | VECT_TAB_OFFSET; 표 내부 플래시에서 // Vector의 재배치 //.
7. 시작 파일 startup_stm32f10x_hd.s에서 코드를 컴파일있다 :
Reset_Handler에는 PROC
내보내기 Reset_Handler [약한]
__main 수입
IMPORT SystemInit
선량률R0 = SystemInit
BLX R0
LDR R0 = __ 주요
BX R0
ENDP의
이유로 시스템이 재설정되면, 먼저 SystemInit 기능을 실행 한 다음 주요 기능은 일반적으로 기능을 SystemInit되지 않는 이유입니다 주요 기능을 실행 어셈블리 코드 지침,.
기술 점 :
1) 시스템 클록 기준이 더 SystemInit 기능 블록도를 참조 이해 될 STM32 경험 VII 학습 : 해석 STM32 클록 및 시스템 블록도 관련 기능 ,
2) 친숙한 파라미터 관련 레지스터.

게시 24 개 원래 기사 · 원 찬양 2 · 조회수 4125

추천

출처blog.csdn.net/Leisure_ksj/article/details/105255484