하여간 스타트 업이 되면

main.c 의 int main(void) 로 점프를 한다.

main에서 최초에 만나는 문장은 RCC_Configuration 이다.

 

------------------------------------------------------

int main(void)
{
    /* System Clocks Configuration */
    RCC_Configuration();

------------------------------------------------------

 

RCC_Configuration 은 hw_config.c 파일에 들어 있다.

H/W 를 초기화 하는 곳인가 보다.

여기서 최초 문장은 SystemInit(); 다

 

------------------------------------------------------

void RCC_Configuration(void)
{
      SystemInit();

/* Enable GPIOA clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

/* Enable GPIOB clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);

/* Enable GPIOC clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);

/* Enable GPIOD clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);

/* Enable USART1 clocks */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);

/* Enable AFIO clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);

/* Enable DMA1 clock */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

}

------------------------------------------------------

 

SystemInit 를 찾아보니 system_stm32f10x.c다.(너무 source를 쪼개둔거 아니야 짜증나)

내용을 살펴봐야 겠다.

 

------------------------------------------------------

void SystemInit (void)

{
    /* Reset the RCC clock configuration to the default reset state(for debug purpose) */

    /* Set HSION bit */
    //일단 클럭쪽 레지스터를 초기화 해서 사용 못하게 한다.

RCC->CR |= (uint32_t)0x00000001; //디버깅을 지원하기위해 HSI ON

/* Reset SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits */
#ifndef STM32F10X_CL //고사양 프로세서 STM32F105,STM32F107 용
RCC->CFGR &= (uint32_t)0xF8FF0000;
#else
RCC->CFGR &= (uint32_t)0xF0FF0000; //RCC->CFGR 레지스터를 clr
#endif /* STM32F10X_CL */

/* Reset HSEON, CSSON and PLLON bits -> clr*/
RCC->CR &= (uint32_t)0xFEF6FFFF;

/* Reset HSEBYP bit -> clr */
RCC->CR &= (uint32_t)0xFFFBFFFF;

/* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits -> clr*/
RCC->CFGR &= (uint32_t)0xFF80FFFF;

#ifndef STM32F10X_CL
/* Disable all interrupts and clear pending bits */
RCC->CIR = 0x009F0000;
#else
/* 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;
#endif /* STM32F10X_CL */

/* Configure the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers */
/* Configure the Flash Latency cycles and enable prefetch buffer */
SetSysClock(); //클럭을 살린다.

}
------------------------------------------------------

 

내용인 즉은 SetSysClock을 실행하기 전에 기존에 사용중인 클럭 모드를 초기화 하는

것이다. SetSysClock은 클럭을 다시 살리는듯 하다. 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
}
------------------------------------------------------

 

지금 보고 있는 장비는 외부 클럭이 12M 이고 내부 시스템 클럭을 pll로 72M 로 만들어서 사용할것이다. 그래서 SetSysClockTo72(); 이 실행된다.

그래서 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); //HSEON 외부 크리스탈 동작

    //주의 STOP 이다. STANBY 모드시 HSE ON 0이됨 -> 다시 설정 해야겠지..
    /* Wait till HSE is ready and if Time out is reached exit */
    do //HSERDY가 SET 되면 사용가능 또는 time out 되면 빠저나감
    {
    HSEStatus = RCC->CR & RCC_CR_HSERDY;
    StartUpCounter++;
    } while((HSEStatus == 0) && (StartUpCounter != HSEStartUp_TimeOut));

 

if ((RCC->CR & RCC_CR_HSERDY) != RESET) //타임 아웃 되어서 나왔는지 확인 한다.
{
    HSEStatus = (uint32_t)0x01; //1이면 안정
}
else
{
    HSEStatus = (uint32_t)0x00; //0이면 불안정
}

 

 

if (HSEStatus == (uint32_t)0x01) //정상 클럭
{
    /* Enable Prefetch Buffer */
    FLASH->ACR |= FLASH_ACR_PRFTBE;

/* Flash 2 wait state */
FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY); //flash access 속도를 0으로 초기화
FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_2; //flsdh access 속도를 2로 -> 40M < SYSCLK < 72M 일때


/* HCLK = SYSCLK */ // AHB,core,memory,DMA
RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;

/* PCLK2 = HCLK */
RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;

/* PCLK1 = HCLK/2 */
RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2;

#ifdef STM32F10X_CL //STM32F105,STM32F107 인경우
/* 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 */
//PLL을 동작 시킨다.
RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE |
RCC_CFGR_PLLMULL));
#ifdef EXT_CLOCK_SOURCE_12M //외부 입력 크리스탈 소스 가 12M으로 사용됨 -> 필요시 수정되어야함
RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL6); // 12M*6 => 72M
#else
RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL9); //8M*9 => 72M
#endif
#endif /* STM32F10X_CL */

 

/* Enable PLL */
RCC->CR |= RCC_CR_PLLON;

/* Wait till PLL is ready */

while((RCC->CR & RCC_CR_PLLRDY) == 0)
{
}

/* Select PLL as system clock source */
RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;

 

/* Wait till PLL is used as system clock source */
    while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08)
    {
    }

}
else //비정상 클럭 무한 loop
{ /* If HSE fails to start-up, the application will have wrong clock
    configuration. User can add here some code to deal with this error */

/* Go to infinite loop */

while (1)
{
}

}

}

------------------------------------------------------

외부 크리스탈 살리고 이상이 없으면 PLL을 살리고 이상이 있으면 무한루프를 돌린다.

여기서 주의할것은 외부 크리스탈이 바뀌면 이부분의 다시보고 PLL등을 맞추어 주어야한다.

 

'공부 > STM32' 카테고리의 다른 글

[STM32] Source 보기 4  (0) 2012.11.09
[STM32] Source 보기 3  (0) 2012.11.09
[STM32] Source 보기 1  (0) 2012.11.09
[STM32] 프로젝트 구성 내용  (0) 2012.11.09
[STM32] 프로젝트의 제구성  (0) 2012.11.09

+ Recent posts