인터럽트를 살리는 루틴이 있다.

 
 
------------------------------------------------------------------------------------
 
int main(void)
{
    uint8_t ch;
 
    /* System Clocks Configuration */
    RCC_Configuration();  //시스템 클럭을 살리고 주변 프리페럴럴 를 살린다.
 
    RCC_GetClocksFreq(&rcc_clocks); //현재 설정된 클럭을 rcc_clocks 스트럭쳐로 가져 온다.

    /* NVIC configuration */
    NVIC_Configuration();   //인터럽트 백터 테이블을 선언 한고, 우선순위 선언, 인터럽트 살리기 

------------------------------------------------------------------------------------
 
 
 
NVIC_Configuration 을 살펴 보면  code를 ram 에서 돌릴지 flash 에서 돌릴지에 따라
 
NVIC가 동작할수 있도록 인터럽트 백터 번지를 선언해 주고

인터럽트를 동작하도록 선언 하다.

 
 
------------------------------------------------------------------------------------
 
void NVIC_Configuration(void)
{
    NVIC_InitTypeDef NVIC_InitStructure;//인터럽트 선언하기 위한 스트럭쳐 정의 함

#ifdef  VECT_TAB_RAM    //선언이 안되어 있음 동작안함  ..
    /* Set the Vector Table base location at 0x20000000 */
    NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);
#else  /* VECT_TAB_FLASH  */    //flash type으로 컴파일
    /* Set the Vector Table base location at 0x08000000 */
    NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);   //인터럽트 백터 번지 설정   
#endif
 
    //기본적으로 H/W 에 인터럽트 테이블 순서에 따라 우선순위가 정해지나
    //Interrupt Priority Register 를 가지고 S/W 적으로 0~255까지 변경할수 있다.
    //그러나 reset,NMI,hard fault 는 가장 높은 우선순위를 가진다.
    //하나씩 다 설정하면 무척 복잡해서 우선순위 group 을 지원하며
    //
    /* Configure one bit for preemption priority */
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); //인터럽트 운선 순위 설정

    /* Enable the EXTI0 Interrupt */
    NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;    //
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
 
    /* Enable the EXTI1 Interrupt */
    NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
}
 
------------------------------------------------------------------------------------
 
 
 
NVIC_SetVectorTable 에보면 assert_param(IS_NVIC_VECTTAB(NVIC_VectTab)); 라는 문장이 있다. 조건이 다르면 에러가 발생되도록 하는것인데 조건이 아래와 같다.
 
#define NVIC_VectTab_RAM             ((uint32_t)0x20000000)
#define NVIC_VectTab_FLASH           ((uint32_t)0x08000000)
#define IS_NVIC_VECTTAB(VECTTAB) (((VECTTAB) == NVIC_VectTab_RAM) || \
                                  ((VECTTAB) == NVIC_VectTab_FLASH))
즉 인터럽럽트 백터 번지가 다른것이 들어올경우 에러 처리 ..

 
 
NVIC_Init() 에서 최종적으로 인터럽트를 동작시키거나 죽이는 역활을 한다.

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

[STM32] Source 보기 7  (0) 2012.11.09
[STM32] Source 보기 6  (0) 2012.11.09
[STM32] Source 보기 4  (0) 2012.11.09
[STM32] Source 보기 3  (0) 2012.11.09
[STM32] SOURCE 보기 2  (0) 2012.11.09
몇일이 지났는데 아직도 main에 초입을 보고 있다. 분발~~
 
 
 
이번에 볼 소스는  RCC_GetClocksFreq 다 .
 
이 함수는 rcc_clocks 라는 스트럭쳐를 상수값으로 전달해서
 
내부 선언된 클럭을 읽어오는 함수다.
---------------------------------------------------------------------------------
 
int main(void)
{
    uint8_t ch;
 
    /* System Clocks Configuration */
    RCC_Configuration();  //시스템 클럭을 살리고 주변 프리페럴럴 를 살린다.
 
    RCC_GetClocksFreq(&rcc_clocks); //현재 설정된 클럭을 rcc_clocks 스트럭쳐로 가져 온다.
---------------------------------------------------------------------------------
 
 
 
스트력처를 보면 클러벌 변수로 선언이 되어 있다.
---------------------------------------------------------------------------------
 
RCC_ClocksTypeDef  rcc_clocks;
 
---------------------------------------------------------------------------------
 
 
 
스트럭처 내용을 보면 typedef 로 선언되어 있고 stm32f10x_rcc.h 에 있다.
특별한기능은 없고 값을 기억하고 있는용으로 사용된다.
---------------------------------------------------------------------------------
 
typedef struct
{
  uint32_t SYSCLK_Frequency;  /*!< returns SYSCLK clock frequency expressed in Hz */
  uint32_t HCLK_Frequency;    /*!< returns HCLK clock frequency expressed in Hz */
  uint32_t PCLK1_Frequency;   /*!< returns PCLK1 clock frequency expressed in Hz */
  uint32_t PCLK2_Frequency;   /*!< returns PCLK2 clock frequency expressed in Hz */
  uint32_t ADCCLK_Frequency;  /*!< returns ADCCLK clock frequency expressed in Hz */
}RCC_ClocksTypeDef;
---------------------------------------------------------------------------------
 
 
 
RCC_GetClocksFreq  소스는 stm32f10x_rcc.c 에 있다. 내용을 보면 아래와 같다.
---------------------------------------------------------------------------------
 
void RCC_GetClocksFreq(RCC_ClocksTypeDef* RCC_Clocks)
{
  uint32_t tmp = 0, pllmull = 0, pllsource = 0, presc = 0;
 
#ifdef  STM32F10X_CL //105,107은 레지스터가 추가되어 있어 계산식이 복잡하다.
  uint32_t prediv1source = 0, prediv1factor = 0, prediv2factor = 0, pll2mull = 0;
#endif /* STM32F10X_CL */
   
  /* Get SYSCLK source -------------------------------------------------------*/
  tmp = RCC->CFGR & CFGR_SWS_Mask;
  /*  SWS 정보 : system 클럭의 소스는 누구?
      00: HSI oscillator used as system clock
      01: HSE oscillator used as system clock
      10: PLL used as system clock
      11: not applicable
  */
 
  switch (tmp)
  {
    case 0x00:  /* HSI used as system clock */
      RCC_Clocks->SYSCLK_Frequency = HSI_Value;   //define 된 값을 가져 온다.
      break;
    case 0x04:  /* HSE used as system clock */
      RCC_Clocks->SYSCLK_Frequency = HSE_Value;   //define 된 값을 가져 온다.
      break;
    case 0x08:  /* PLL used as system clock */
 
      /* Get PLL clock source and multiplication factor ----------------------*/
      pllmull = RCC->CFGR & CFGR_PLLMull_Mask;  //pll 입력 주파수 * 몇배할값
      pllsource = RCC->CFGR & CFGR_PLLSRC_Mask; //pll 입력: 외부클럭 (1값)이 바로 들어오는지 내부클럭/2 (0값)되서 들어오는지
     
#ifndef STM32F10X_CL      
      //pllmull 이 0 이면 pll은 *2로 동작
      //pllmull 이 1 이면 pll은 *3로 동작 .....
      pllmull = ( pllmull >> 18) + 2;
     
      if (pllsource == 0x00)  //내부클럭/2 * pll배수
      {/* HSI oscillator clock divided by 2 selected as PLL clock entry */
        RCC_Clocks->SYSCLK_Frequency = (HSI_Value >> 1) * pllmull;
      }
      else  //외부 클럭 * pll 배수 또는   외부 클럭/2 * pll
      {/* HSE selected as PLL clock entry */
        if ((RCC->CFGR & CFGR_PLLXTPRE_Mask) != (uint32_t)RESET)
        {/* HSE oscillator clock divided by 2 */
          RCC_Clocks->SYSCLK_Frequency = (HSE_Value >> 1) * pllmull;
        }
        else
        {
          RCC_Clocks->SYSCLK_Frequency = HSE_Value * pllmull;
        }
      }
#else    //성능 좋은 놈들  105,107
      pllmull = pllmull >> 18;
     
      if (pllmull != 0x0D)
      {
        //pllmull 이 0 이면 pll은 *2로 동작
        //pllmull 이 1 이면 pll은 *3로 동작
        pllmull += 2;
      }
      else
      { /* PLL multiplication factor = PLL input clock * 6.5 */
 
        pllmull = 13 / 2;
      }
           
      if (pllsource == 0x00)  //내부클럭/2 * pll배수
      {/* HSI oscillator clock divided by 2 selected as PLL clock entry */
        RCC_Clocks->SYSCLK_Frequency = (HSI_Value >> 1) * pllmull;
      }
      else  //외부 클럭 * pll 배수
      {/* PREDIV1 selected as PLL clock entry */
       
        /* Get PREDIV1 clock source and division factor */
        prediv1source = RCC->CFGR2 & CFGR2_PREDIV1SRC;
        prediv1factor = (RCC->CFGR2 & CFGR2_PREDIV1) + 1;
       
        if (prediv1source == 0)
        { /* HSE oscillator clock selected as PREDIV1 clock entry */
          RCC_Clocks->SYSCLK_Frequency = (HSE_Value / prediv1factor) * pllmull;         
        }
        else
        {/* PLL2 clock selected as PREDIV1 clock entry */
         
          /* Get PREDIV2 division factor and PLL2 multiplication factor */
          prediv2factor = ((RCC->CFGR2 & CFGR2_PREDIV2) >> 4) + 1;
          pll2mull = ((RCC->CFGR2 & CFGR2_PLL2MUL) >> 8 ) + 2;
          RCC_Clocks->SYSCLK_Frequency = (((HSE_Value / prediv2factor) * pll2mull) / prediv1factor) * pllmull;                        
        }
      }
#endif /* STM32F10X_CL */
      break;
 
    default:
      RCC_Clocks->SYSCLK_Frequency = HSI_Value;
      break;
  }
 
  /* Compute HCLK, PCLK1, PCLK2 and ADCCLK clocks frequencies ----------------*/
  /* Get HCLK prescaler */
  tmp = RCC->CFGR & CFGR_HPRE_Set_Mask;
  tmp = tmp >> 4;
  presc = APBAHBPrescTable[tmp];
  /* HCLK clock frequency */ //core,AHB,menory,DMA 용
  RCC_Clocks->HCLK_Frequency = RCC_Clocks->SYSCLK_Frequency >> presc;
  /* Get PCLK1 prescaler */
  tmp = RCC->CFGR & CFGR_PPRE1_Set_Mask;
  tmp = tmp >> 8;
  presc = APBAHBPrescTable[tmp];
  /* PCLK1 clock frequency */ //APB1 용 peripherals
  //USART2,USART3,UART4,SPI/I2S2,SPI/I2S3,I2C1,I2C2,TIM2,TIM3,TIM4,TIM5,TIM6,TIM7가 사용
  RCC_Clocks->PCLK1_Frequency = RCC_Clocks->HCLK_Frequency >> presc;
  /* Get PCLK2 prescaler */
  tmp = RCC->CFGR & CFGR_PPRE2_Set_Mask;
  tmp = tmp >> 11;
  presc = APBAHBPrescTable[tmp];
  /* PCLK2 clock frequency */  //APB2용 peripherals
  //USART1,SPI1,ADC1,ADC3,TIM1,TIM8 가 사용
  RCC_Clocks->PCLK2_Frequency = RCC_Clocks->HCLK_Frequency >> presc;
  /* Get ADCCLK prescaler */
  tmp = RCC->CFGR & CFGR_ADCPRE_Set_Mask;
  tmp = tmp >> 14;
  presc = ADCPrescTable[tmp];
  /* ADCCLK clock frequency */  //ADC용 클럭
  //타이머에 의한 ADC 동작을 만들수도 있고 ADC클럭으로 이벤트 동작을 할수도 있다.
  RCC_Clocks->ADCCLK_Frequency = RCC_Clocks->PCLK2_Frequency / presc;
}
 
---------------------------------------------------------------------------------
 
 
 
* STM32F10X_CL  define 문을 잘 보면서 소스를 봐야지 자꾸 잘못 본다.

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

[STM32] Source 보기 6  (0) 2012.11.09
[STM32] Source 보기 5  (0) 2012.11.09
[STM32] Source 보기 3  (0) 2012.11.09
[STM32] SOURCE 보기 2  (0) 2012.11.09
[STM32] Source 보기 1  (0) 2012.11.09

저번 소스에서 SystemInit 에서 system 클럭을 죽였다 다시 살렸다.

이번에 그 이후를 보면 ..

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

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);
}

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

SYSTEM 클럭은 용도에 따라 분주를 해서 HCLK,FCLK,APB1,APB2 등에 사용된다.

72M 를 IO등에 바로 넣으면 좋겠지만 그럼 용도에 안맞을수도 있고 가격도 올라갈 것이다.

CPU는 가장 빠르게 동작해야 하니까 72M를 쓰고 램하고 연결되는 쪽은 가장 빨라야하니 72M

IO는 적당해도 되니 24M ... 이런식이다. (이건파워제어 레지스터하고 묶여있다.)

또다른 용도는 클럭이 안들어가면 그에 연결된 장치가 안돌것이고 안돌면 전류를 가장 작게

먹을것이니 저전력이 될것이다. 이런 내용이다.

이것은 저번 소스에서 보였던 RCC_CFGR 레지스터를 맞추어 설정하면 된다.

또다른 것은 APB1은 PCLK1을 설정하고 이것은 타이머2,3,4,5,6,7 이나 APB1에 붇어있는 디바이스를

제어하게 된다는것 이다.

어떤놈에 어떤것이 있는지 defile 문을 보자 stm32f10x_rcc.h에 들어 있다.

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

#define RCC_AHBPeriph_DMA1 ((uint32_t)0x00000001)
#define RCC_AHBPeriph_DMA2 ((uint32_t)0x00000002)
#define RCC_AHBPeriph_SRAM ((uint32_t)0x00000004)
#define RCC_AHBPeriph_FLITF ((uint32_t)0x00000010)
#define RCC_AHBPeriph_CRC ((uint32_t)0x00000040)

#define RCC_AHBPeriph_FSMC ((uint32_t)0x00000100)
#define RCC_AHBPeriph_SDIO ((uint32_t)0x00000400)
#define IS_RCC_AHB_PERIPH(PERIPH) ((((PERIPH) & 0xFFFFFAA8) == 0x00) && ((PERIPH) != 0x00))

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

AHB에는 DMA1,DMA2.,SRAM,FLITF,CRC,FSMC,SDIO 가 붇어 있다.

정확하게 보려면 블럭도를 보고 이해 해야한다. 레지스터를 일일이 보면 컥 넘 많다.

다른거 할때마다 좀씩 봐야지

위에 소스를 보면 GPIOA , GPIOB , GPIOC ,GPIOD, USART1, AFIO, DMA1 를 살린다.

참고로 AFIO는 IO 기능을 변경해주는 놈이다. PORTB.6번이었던놈이 설정을 하면 PORTD.12번이

된다. 카멜레온 같은놈 .. ㅋㅋ

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

[STM32] Source 보기 5  (0) 2012.11.09
[STM32] Source 보기 4  (0) 2012.11.09
[STM32] SOURCE 보기 2  (0) 2012.11.09
[STM32] Source 보기 1  (0) 2012.11.09
[STM32] 프로젝트 구성 내용  (0) 2012.11.09

하여간 스타트 업이 되면

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

iar 로 되어 있는 프로젝트 소스를 확인해 보기로 했다.

option 의 linker 부분을 보면 config 창에

STM32F10x-FLASH.icf 가 있다. 여기부터 봐야 겠지..

 

------ STM32F10x-FLASH.ic 내용 ---------------------

/*###ICF### Section handled by ICF editor, don't touch! ****/
/*-Editor annotation file-*/
/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\a_v1_0.xml" */
/*-Specials-*/
define symbol __ICFEDIT_intvec_start__ = 0x08000000; //백터 번지가 여기부터란다.
/*-Memory Regions-*/
define symbol __ICFEDIT_region_ROM_start__ = 0x08000000 ; //ROM의 start번지 flash의 시작번지다
define symbol __ICFEDIT_region_ROM_end__ = 0x0807FFFF; //>>ROM의 끝번지 flash의 끝번지
define symbol __ICFEDIT_region_RAM_start__ = 0x20000000; //>>RAM의 첫번지 , 내부램번지
define symbol __ICFEDIT_region_RAM_end__ = 0x2000FFFF; //>>RAM의 끝번지, 내부램번지
/*-Sizes-*/
define symbol __ICFEDIT_size_cstack__ = 0x400; //>>스텍용량 0x400잡았다. 좀 더 키우는게 좋을듯 하긴하다.
define symbol __ICFEDIT_size_heap__ = 0x200; //>>heap 사이즈다. 멜록을 더잡거나 printf를 많이 쓰면 더 키워야 할듯 하다.
/**** End of ICF editor section. ###ICF###*/

//>>아래는 메모리 알아서 잡는데 위쪽 메모리 번지만 바꾸면 알아서 변경될듯 하다.

define memory mem with size = 4G;
define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];

define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };

initialize by copy { readwrite };
do not initialize { section .noinit };

place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };

place in ROM_region { readonly };
place in RAM_region { readwrite,
block CSTACK, block HEAP };

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

 

메모리 잡는것은 다른 CPU 잡는것보다는 명확해 보여서 좋다. keil은 ide 환경에서 바로

설정이 가능한것으로 알고 있는데 iar은 찾아보니 그런내용이 config쪽에 없네 ..

그냥 pass

부팅되면 역시 스타트 번지의 asm 쪽 코드가 실행될것이다. 자 어떤 놈이가 찾아보니

startup_stm32f10x_md.s 라는 파일이 있다.

역시 cortex 다 인터럽트 백터만 잔뜩 모여 있다. 예전 arm7이나 arm9은 이부분 source를

꼭 확인 하려면 asm을 찾아봐야 했는데. (모 예전것은 거의 레지스터에 있는것을 스텍에 넣어주는

코드가 거의 대부분 이었다.) 스텍처리를 cpu가 알아서 하니 startup code가 무지 간단해

지는구나 .. 인터럽트 속도가 무지 빨리질듯 하다.

예를 들어 DMA1의 Channel1의 인터럽트가 발생하면

인터럽트 번지에 점프를 할꺼고 거기에 아래와 같이 설정되어 있어서

 

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

DCD DMA1_Channel1_IRQHandler ; DMA1 Channel 1 -> 인덱스를 알려줌
--------------------------------------------------------

 

해당번지의 내용 DMA1_Channel1_IRQHandler 소스쪽으로 점프를 할것이다.

 

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

PUBWEAK DMA1_Channel1_IRQHandler
SECTION .text:CODE:REORDER(1)
DMA1_Channel1_IRQHandler -> 인덱스
B DMA1_Channel1_IRQHandler -> 요기서 csource 로 점프

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

 

이후 stm32f10x_it.c 에 있는 void DMA1_Channel1_IRQHandler(void) 함수로

가게 된다. 나는 이 함수에 인터럽트 처리관련 source 를 짜면 된다. ㅋㅋㅋ

 

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

void DMA1_Channel1_IRQHandler(void)
{
    Send_Buffer[0] = 0x07;

if((ADC_ConvertedValueX >>4) - (ADC_ConvertedValueX_1 >>4) > 4)
{
    Send_Buffer[1] = (uint8_t)(ADC_ConvertedValueX >>4);
    UserToPMABufferCopy(Send_Buffer, ENDP1_TXADDR, 2);
    SetEPTxCount(ENDP1, 2);
    SetEPTxValid(ENDP1);
    ADC_ConvertedValueX_1 = ADC_ConvertedValueX;
}

DMA_ClearFlag(DMA1_FLAG_TC1);
}
--------------------------------------------------------

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

[STM32] Source 보기 3  (0) 2012.11.09
[STM32] SOURCE 보기 2  (0) 2012.11.09
[STM32] 프로젝트 구성 내용  (0) 2012.11.09
[STM32] 프로젝트의 제구성  (0) 2012.11.09
[STM32] WRITER ..  (0) 2012.11.09

iar로 만든 프로젝트 내용을 정리해본다.

 

 

 

 

프로젝트 설정 내용이다. (기본에서 다른 것만 표시했다.)

 

 

 

 

 

 

 

 

 

이상

 

 

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

[STM32] Source 보기 3  (0) 2012.11.09
[STM32] SOURCE 보기 2  (0) 2012.11.09
[STM32] Source 보기 1  (0) 2012.11.09
[STM32] 프로젝트의 제구성  (0) 2012.11.09
[STM32] WRITER ..  (0) 2012.11.09

Mango-Z1 용 예제 프로그램과 라이브러리를 받았다.

www.e-crazyboys.com 에서 mango 보드시리즈를 사면 받을수 있다.

받은 소스라 공개를 하기 그렇다. 공개안하는것이 예의 일듯...

http://cafe.naver.com/embeddedcrazyboys.cafe에 가면 관련 내용이 있다.

 

 

 

 

 

디렉토리 구조다. 원본은 source 와 라이브러리 디렉토리가 별도로 분리 되어 있다.

프로젝트를 여러개를 혼용으로 사용하기 위해 project 디렉토리를 만들어 두었다.

참 잘 만든 구조다.

 

그런데 iar 만 쓰려는 나에게는 군더더기가 많다.

source 용량이 많아 지더라도 프로젝트와 라이브러리는 묶는것을 좋아한다.

그래야 라이브러리를 수정하는 상황이 발생해도 날자가 다른 소스에

영향을 주지 않는다. (난 날자별 프로젝트를 만드는 버릇이 있다.)

그래서 디렉토리를 다시 모아 소스를 만들었다.

 

 

 

091117 이라는 디렉토리에 iar 프로젝트 파일을 넣어 두었다.

그하위 디렉토리는 각각의 source 들이다.

 

 

Debug : Debug 모드로 컴파일시에 생성되는 파일이 모임

Release : Release 모드로 컴파일시에 생성되는 파일이 모임

lib : st 에서 배포하는 라이브러리 모임

setting : iar 컴파일러 에서 생성하는 설정값이 모임

src : 실제 제작된 source 모임

) icf 파일은 가장 상위 디렉토리에 넣어 두었다.

 

 

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

[STM32] Source 보기 3  (0) 2012.11.09
[STM32] SOURCE 보기 2  (0) 2012.11.09
[STM32] Source 보기 1  (0) 2012.11.09
[STM32] 프로젝트 구성 내용  (0) 2012.11.09
[STM32] WRITER ..  (0) 2012.11.09

STM32 를 공부하기 시작했다.

www.e-crazyboys.com Mango-Z1 보그를 가지고 하고 있다.

먼저 개발 환경 구축 ..

컴파일러 는 IAR 또는 RIDE 중 하나를 사용해야 할듯 하다. IAR 을 컴파일러이며

RIDE 는 컴파일러는 GCC 컴파일러를 사용하고 여기에 IDE 를 연결해서 사용한다.

IAR에 좀더 익숙하다. 그래서 IAR로 해보기로 했다.

디버거는 기존에 가지고 있는 Jlink 를 이용하기로 했다.

 

 

 

 

인식이 잘된다..

Jlink 같은 디버거및 다운로더가 없어도 flash Writer 기능을 STM32는 가지고 있다.

먼저 boot mode pin를 이용해서 STM32 boot mode System memory 로 변경한다.

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

boot0 pin 1 boot1 pin 0으로 해두어야 한다.

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

고리고 www.st.com 사이트에서 받은 전용 다운로드 지원 프로그램을 실행한다.

http://www.st.com/stonline/products/support/micro/files/um0462.zip
http://www.st.com/stonline/products/literature/um/13916.pdf

압축을 풀어 인스톨을 하고 실행하면 연결된 케이블을 선택한다.

 

 

 

 

연결이 잘되어 있으면 인식되는 창인나온다.

인식이 잘 안되면 Reset 을 누르고 다시 시도 한다.

 

 

 

 

 

 

 

자 이제 쓰거나 지우거나 등 다양한 기능을 활용할수 있다.

다운로드후 바로 실행도 가능하다.

현재 사용되는 보드의 디바이스인 STM32F103RB 외에 좀 고사양의 STM32 boot에서 USB

방식도 지원한단다.. 나중에 디바이스를 사용하게 되면 테스트를 해봐야 겠다.

 

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

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

+ Recent posts