Showing posts with label STM32F2xx. Show all posts
Showing posts with label STM32F2xx. Show all posts

Saturday, October 5, 2013

Programming Example : System Tick Timer


#include "stm32f2xx.h"
static __IO uint32_t TimingDelay;
void Delay(__IO uint32_t nTime);

int main(void)
{
  RCC_ClocksTypeDef rcc_clocks;

  RCC_GetClocksFreq(&rcc_clocks);

  if (SysTick_Config(rcc_clocks.SYSCLK_Frequency / 1000))
  {
    /* Capture error */
    while (1);
  }

  while (1)
  {
    /* Todo: Toggle LED, etc. */

    ...

    /* Insert 50 ms delay */
    Delay(50);
  }
}


void Delay(__IO uint32_t nTime)
{ 
  TimingDelay = nTime;
  while(TimingDelay != 0);
}

void TimingDelay_Decrement(void)
{
  if (TimingDelay != 0x00)
  {
    TimingDelay--;
  }
}

/* System Tick Timer Handler */
void SysTick_Handler(void)
{
  TimingDelay_Decrement();
}


/*
<Get System Clock Frequency>
@reg1  RCC->CFGR
@desc  Bits 15:13, PPRE2: APB high-speed prescaler (APB2)
       Bits 12:10, PPRE1: APB low-speed prescaler (APB1)
       Bits 7:4, HPRE: AHB prescaler
       Bits 3:2, SWS: System clock switch status
@reg2  RCC->PLLCFGR
@desc  Bit 22, PLLSRC: Main PLL(PLL) and audio PLL(PLLI2S) entry clock source
       Bits 17:16, PLLP: Main PLL(PLL) division factor for main system clock
       Bits 14:6, PLLN: Main PLL(PLL) multiplication factor for VCO
       Bits 5:0, PLLM: Division factor for the main PLL(PLL) and audio PLL(PLLI2S) input clock
@fn    void RCC_GetClocksFreq(RCC_ClocksTypeDef* RCC_Clocks);
@ref   stm32f2xx_rcc.h

<System Tick Timer Configuration>
@reg1   SysTick->LOAD
@desc  Bits 23:0, RELOAD[23:0]: Reload value can be any value in range of 0x00000001 ~ 0x00FFFFFF
@reg2   SysTick->VAL
@desc  Bits 23:0, CURRENT[23:0]: Current count value of the SysTick counter
@reg3   SysTick->CTRL
@desc  Bit 16, COUNTFLAG: Returns 1 if timer counted to 0 since last time this was read. Software can use COUNTFLAG to determine if SysTick has ever counted to zero.
       Bit 2, CLKSOURCE: Clock source selection
       Bit 1, TICKINT: SysTick exception request enable
       Bit 0, ENABLE: Counter enable
@reg4  SCB->SHPR3
@desc  Bits 31:24, PRI_15[7:0]: Priority of system handler 15, SysTick exception
@fn1   __STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
@fn2   __STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
@param SysTick_IRQn
@ref   stm32f2xx.h, core_cm3.h
*/

Sunday, September 29, 2013

Programming Example : EXTI

#include "stm32f2xx.h"

void GPIO_ConfigInputMode(void);
void EXTI_Config(void);
void NVIC_Config(void);


int main(void)
{

  /* Configure EXTI Line0 (Connected to PA0 pin) in interrupt mode */
  GPIO_ConfigInputMode();
  EXTI_Config();

  NVIC_Config();

  /* Generate software interrupt: simulate rising edge applied on EXTI0 Line */
  EXTI_GenerateSWInterrupt(EXTI_Line0);

  while (1);
}

void GPIO_ConfigInputMode(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;

 
 /* Enable GPIOA's AHB interface clock */
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
 
  /* Configure PA0 pin in input mode */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
  GPIO_Init(GPIOA, &GPIO_InitStructure); 
}

void EXTI_Config(void)
{
  EXTI_InitTypeDef EXTI_InitStructure;

  /* Enable SYSCFG's APB interface clock */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
 
  /* Connect EXTI Line0 to PA0 pin */
  SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource0);

  /* Configure EXTI line0 */
  EXTI_InitStructure.EXTI_Line = EXTI_Line0;
  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
  EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  EXTI_Init(&EXTI_InitStructure); 
}


void NVIC_Config(void)
{
  NVIC_InitTypeDef NVIC_InitStructure;

  /* Enable and set EXTI Line0 Interrupt to the lowest priority */

  NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
}

/* EXTI0 Line interrupt handler */
void EXTI0_IRQHandler(void)
{
  if(EXTI_GetITStatus(EXTI_Line0) != RESET)
  {
    /* Todo: Toggle LED, etc. */
    ...

    /* Clear the EXTI line 0 pending bit */
    EXTI_ClearITPendingBit(EXTI_Line0);
  }
}


/*
<GPIO Configuration as a input mode>
@skip  Refer to "Programming Example : GPIO - Input Mode"

<Connect External Interrupt Line to GPIO pin>
@reg   SYSCFG->EXTICR (0~3)
@desc  Bits 15:0, EXTIx[3:0]: EXTI x configuration
@fn    void SYSCFG_EXTILineConfig(uint8_t EXTI_PortSourceGPIOx, uint8_t EXTI_PinSourcex)
@ref   stm32f2xx_syscfg.h

<External Interrupt Configuration>
@reg   EXTI->IMR, EXTI->EMR, EXTI->RTSR, EXTI->FTSR
@desc  [EXTI->IMR, EXTI->EMR] Bits 22:0, MRx: interrupt/event mask on line x
       [EXTI->RTSR, EXTI->FTSR] Bits 22:0, TRx: rising/falling trigger event configuration bit on line x
@fn    void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct)
@ref   stm32f2xx_exti.h


<NVIC Configuration>
@reg   NVIC->IPRx, NVIC->ISERx, NVIC->ICERx
@desc  [NVIC->IPRx] IPR0 ~ IPR20: Interrupt priority register, IP[0] ~ IP[80]
       [NVIC->ISERx] Bits 31:0, SETENA[31:0]: Interrupt set-enable bits. Write: 0(No effect), 1(Enable interrupt)
       [NVIC->ICERx] Bits 31:0, SETENA[31:0]: Interrupt clear-enable bits. Write: 0(No effect), 1(Clear interrupt)
@fn    void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct)
@param EXTI0_IRQn, NVIC_InitTypeDef
@ref   stm32f2xx.h, misc.h

<External Interrupt Triggering by SW>
@reg   EXTI->SWIER
@desc  Bits 22:0, SWIERx: software interrupt on line x
@fn    void EXTI_GenerateSWInterrupt(uint32_t EXTI_Line)
@param EXTI_Line0
@ref   stm32f2xx_exti.h

<External Interrupt Handling>
1. Get external interrupt status
@reg   EXTI->IMR, EXTI->PR
@desc  [EXTI->IMR] Bits 22:0, MRx: interrupt/event mask on line x
       [EXTI->PR] Bits 22:0, PRx: pending bit
@fn    ITStatus EXTI_GetITStatus(uint32_t EXTI_Line)
@param EXTI_Line0
@ref   stm32f2xx_exti.h

2. Clear interrupt pending bit
@reg   EXTI->PR
@desc  Bits 22:0, PRx: pending bit, cleared by writing a 1 to the bit
@fn    void EXTI_ClearITPendingBit(uint32_t EXTI_Line)
@param EXTI_Line0
@ref   stm32f2xx_exti.h
*/

Saturday, September 28, 2013

Programming Example : RCC


#include "stm32f2xx.h"

/* 
PLL clock flow:
    HSE_VALUE = 25MHz

    PLL_VCO_Input = (HSE_VALUE or HSI_VALUE) / PLL_M 
                  = 25MHz / 25
                  = 1MHz

    PLL_VCO = PLL_VCO_Input * PLL_N
            = 1MHz * 240
            = 240MHz

    SYSCLK = PLL_VCO / PLL_P
           = 240MHz / 2
           = 120MHz

    PLL48CK = PLL_VCO / PLL_Q
            = 240MHz / 5
            = 48MHz

Range:
    PLL_VCO_Input: 1 ~ 2MHz, 2MHz is recommended.
    PLL_VCO: 64 ~ 432MHz
    PLL48CK: requires 48MHz(USB OTG FS)
             requires lower than or equal to 48MHz(SDIO, RNG)

    PLL_M: 2 ~ 63
    PLL_N: 64 ~ 432
    PLL_P: 2, 4, 6, 8
    PLL_Q: 2 ~ 15
*/

#define PLL_M   25
#define PLL_N   240
#define PLL_P   2
#define PLL_Q   5

void FLASH_Config(void);
void RCC_PeriphClockConfig(void);

int main(void)
{
  __IO uint32_t HSEStartUpStatus = 0;

  /* Enable HSE, and wait till HSE is ready */
  RCC_HSEConfig(RCC_HSE_ON);
  HSEStartUpStatus = RCC_WaitForHSEStartUp();

  if (HSEStartUpStatus == SUCCESS)
  {
    /* Flash Configuration */
    FLASH_Config();
 
    /* Peripheral Clock Configuration */
    RCC_PeriphClockConfig();
     
    /* Config the main PLL Clock to 120MHz */
    RCC_PLLConfig(RCC_PLLSource_HSE, PLL_M, PLL_N, PLL_P, PLL_Q);
 
    /* Enable the main PLL, and wait till the main PLL is ready */
    RCC_PLLCmd(ENABLE);
    while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);
 
    /* Select the main PLL as system clock source, 
      and wait till the main PLL is used as system clock source */
    RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
    while (RCC_GetSYSCLKSource() != RCC_CFGR_SWS_PLL);
  }
  else
  {
    /* If HSE fails to start up, user can add here some code 
      to deal with this error */
  }
}

void FLASH_Config(void)
{
  /* Flash 3 wait state, prefetch buffer and cache ON */
  FLASH_SetLatency(FLASH_Latency_3);
  FLASH_PrefetchBufferCmd(ENABLE);
  FLASH_InstructionCacheCmd(ENABLE);
  FLASH_DataCacheCmd(ENABLE);
}

void RCC_PeriphClockConfig(void)
{
  /* HCLK, PCLK1, PCLK2 Configuration */
  RCC_HCLKConfig(RCC_SYSCLK_Div1);
  RCC_PCLK2Config(RCC_HCLK_Div2);
  RCC_PCLK1Config(RCC_HCLK_Div4);
}


/*
<HSE Enable & Ready>
1. HSE Enable
@reg   RCC->CR
@desc  Bit 18, HSEBYP: HSE clock bypass
       Bit 16, HSEON: HSE clock enable
@fn    void RCC_HSEConfig(uint8_t RCC_HSE)
@param RCC_HSE_ON
@ref   stm32f2xx_rcc.h

2. HSE Ready
@reg   RCC->CR
@desc  Bit 17, HSERDY: HSE clock ready flag
@fn    ErrorStatus RCC_WaitForHSEStartUp(void)
       FlagStatus RCC_GetFlagStatus(uint8_t RCC_FLAG)
@param HSE_STARTUP_TIMEOUT, RCC_FLAG_HSERDY
@ref   stm32f2xx.h, stm32f2xx_rcc.h


<Flash Configuration>
1. Latency cycle, Instruction prefetch, Instruction cache, Data cache
@reg   FLASH->ACR
@desc  Bit 10, DCEN: Data cache enable
       Bit 9, ICEN: Instruction cache enable
       Bit 8, PRFTEN: Prefetch enable
       Bits 2:0, LATENCY: Wait state for latency
@fn    void FLASH_SetLatency(uint32_t FLASH_Latency)
       void FLASH_PrefetchBufferCmd(FunctionalState NewState)
       void FLASH_InstructionCacheCmd(FunctionalState NewState)
       void FLASH_DataCacheCmd(FunctionalState NewState)
@param FLASH_Latency_3
@ref   stm32f2xx_flash.h


<Peripheral Clock Configuration>
1. Peripheral clock prescaler
@reg   RCC->CFGR
@desc  Bits 15:13, PPRE2: APB high-speed prescaler (APB2), must not exceed 60MHz
       Bits 12:10, PPRE1: APB low-speed prescaler (APB1), must not exceed 30MHz
       Bits 7:4, HPRE: AHB prescaler
@fn    void RCC_HCLKConfig(uint32_t RCC_SYSCLK)
       void RCC_PCLK1Config(uint32_t RCC_HCLK)
       void RCC_PCLK2Config(uint32_t RCC_HCLK)
@param RCC_SYSCLK_Div1, RCC_HCLK_Div2, RCC_HCLK_Div4
@ref   stm32f2xx_rcc.h


<PLL Configuration>
@reg   RCC->PLLCFGR
@desc  Bits 27:24, PLLQ: Main PLL division factor for USB OTG FS, SDIO, RNG clock
       Bit 22, PLLSRC: Main PLL(PLL) and audio PLL(PLLI2S) entry clock source
       Bits 17:16, PLLP: Main PLL division factor for main system clock
       Bits 14:6, PLLN: Main PLL multiplication factor for VCO
       Bits 5:0, PLLM: Division factor for main PLL(PLL) and audio PLL(PLLI2S) input clock
@fn    void RCC_PLLConfig(uint32_t RCC_PLLSource, uint32_t PLLM, uint32_t PLLN, uint32_t PLLP, uint32_t PLLQ)
@param RCC_PLLSource_HSE
@ref   stm32f2xx_rcc.h

<Main PLL Enable & Ready>
1. Main PLL Enable
@reg   RCC->CR
@desc  Bit 24, PLLON: Main PLL enable
@fn    void RCC_PLLCmd(FunctionalState NewState)
@param CR_PLLON_BB (using Bit Banding)
@ref   stm32f2xx_rcc.h

2. Main PLL Ready
@reg   RCC->CR
@desc  Bit 25, PLLRDY: Main PLL clock ready flag
@fn    FlagStatus RCC_GetFlagStatus(uint8_t RCC_FLAG)
@param RCC_FLAG_PLLRDY
@ref   stm32f2xx_rcc.h


<System Clock Configuration as the main PLL>
1. System clock configuration

@reg   RCC->CFGR

@desc  Bits 1:0, SW: System clock switch

@fn    void RCC_SYSCLKConfig(uint32_t RCC_SYSCLKSource)
@param RCC_SYSCLKSource_PLLCLK
@ref   stm32f2xx_rcc.h

2. Check the system clock status

1. System clock configuration



@reg   RCC->CFGR

@desc  Bits 3:2, SWS: System clock switch status

@fn    uint8_t RCC_GetSYSCLKSource(void)
@param RCC_CFGR_SWS_PLL
@ref   stm32f2xx.h
*/

Programming Example : USART

#include "stm32f2xx.h"

void GPIO_Config_AFMode(void);
void USART3_Config(void);


int main(void)

{

  GPIO_Config_AFMode();
  USART3_Config();

  while (1)
  {
    USART_SendData(USART3, 0xA5);
    while (USART_GetFlagStatus(USART3, USART_FLAG_TC) == RESET);
  }
}

void GPIO_Config_AFMode(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;

  /* Enable GPIOC Clock */
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);

  /* Connect PC10, PC11 to USART3_Tx, USART3_Rx */
  GPIO_PinAFConfig(GPIOC, GPIO_PinSource10, GPIO_AF_USART3);
  GPIO_PinAFConfig(GPIOC, GPIO_PinSource11, GPIO_AF_USART3);

  /* Configure USART3_Tx and USART3_Rx as alternative function */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
  GPIO_Init(GPIOC, &GPIO_InitStructure);
}

void USART3_Config(void)
{
  USART_InitTypeDef USART_InitStructure;

  /* Enable USART3 Clock */
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);

  /* Configure USART3 */

  USART_InitStructure.USART_BaudRate = 115200;
  USART_InitStructure.USART_WordLength = USART_WordLength_8b;
  USART_InitStructure.USART_StopBits = USART_StopBits_1;
  USART_InitStructure.USART_Parity = USART_Parity_No;
  USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
  USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
  USART_Init(USART3, &USART_InitStructure);

  /* Enable USART3 */

  USART_Cmd(USART3, ENABLE);
}


/*

<USART Configuration>

1. USART Clock Enable
@reg   RCC->AHB1ENR
@fn    void RCC_APB1PeriphClockCmd(uint32_t RCC_APB1Periph, FunctionalState NewState)
@param RCC_APB1Periph_USART3, ENABLE
@ref   stm32f2xx_rcc.h, stm32f2xx.h

2. Configure USART port (1) Word length, Parity, Mode

@reg   USARTx->CR1
@desc  Bit 12, M: Word length bits, 
       Bit 10, PCE: Parity control enable (by Hardware), 
       Bit 9, PS: Parity Selection (Even / Odd),
       Bit 3, TE: Transmitter enable,
       Bit 2, RE: Receiver enable      
@param USART_WordLength_8b, USART_Parity_No, USART_Mode_Rx, USART_Mode_Tx
@ref   stm32f2xx_usart.h

3. Configure USART port (2) Stop bits
@reg   USARTx->CR2
@desc   Bits 13:12, STOP: STOP bits configuration
@param USART_StopBits_1
@ref   stm32f2xx_usart.h

4. Configure USART port (3) Hardware flow control
@reg   USARTx->CR3
@desc  Bit 9, CTSE: CTS enable
       Bit 8, RTSE: RTS enable
@param USART_HardwareFlowControl_None
@ref   stm32f2xx_usart.h

5. Configure USART port (4) Baudrate
@reg   USARTx->BRR
@desc  Bits 15:4, DIV_Mantissa[11:0]: Mantissa of USARTDIV
       Bits 3:0, DIV_Fraction[3:0]: Fraction of USARTDIV
@param USART_CR1_OVER8 (Oversampling)
@ref   stm32f2xx_usart.h

6. USART enable
@reg   USARTx->CR1
@desc  Bit 13, UE: USART enable
@param USART_CR1_UE
@ref   stm32f2xx_usart.h


<USART Data Transmission>
1. USART Send Data
@reg   USARTx->DR
@desc  Bits 8:0, DR[8:0]: Data value to send or receive
@fn    void USART_SendData(USART_TypeDef* USARTx, uint16_t Data)
@param USART3
@ref   stm32f2xx.h

2. USART Check Status
@reg   USARTx->SR
@desc  Bit 6, TC: Transmission complete
@fn    FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_t USART_FLAG)
@param USART3, USART_FLAG_TC
@ref   stm32f2xx.h, stm32f2xx_usart.h
*/

Programming Example : GPIO - Alternative Function Mode

#include "stm32f2xx.h"

void GPIO_Config_AFMode(void);

int main(void)

{
  GPIO_Config_AFMode(); // to be used as an USART Tx/Rx I/Os
}

void GPIO_Config_AFMode(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;

  /* Enable GPIOD Clock */

  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);

  /* Connect PD5, PD6 to USART2_Tx/Rx */

  GPIO_PinAFConfig(GPIOD, GPIO_PinSource5, GPIO_AF_USART2);
  GPIO_PinAFConfig(GPIOD, GPIO_PinSource6, GPIO_AF_USART2);

  /* Configure PD5, PD6 as alternative function */

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
  GPIO_Init(GPIOC, &GPIO_InitStructure);
}

/*
<Alternative function mode>

1. Enable GPIOA's AHB interface clock

@reg   RCC->AHB1ENR
@fn    void RCC_AHB1PeriphClockCmd(uint32_t RCC_AHB1Periph, FunctionalState NewState)
@param RCC_AHB1Periph_GPIOA, ENABLE
@ref   stm32f2xx_rcc.h, stm32f2xx.h

2. Connect GPIO pin to USART_Tx/Rx

@reg   GPIOx->AFR
@fn    void GPIO_PinAFConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_PinSource, uint8_t GPIO_AF)
@param GPIOC, GPIO_PinSource5, GPIO_PinSource6, GPIO_AF_USART2
@ref   stm32f2xx_gpio.h

3. Configure GPIO pin in alternative function mode

@reg   GPIOx->MODER, GPIOx->OSPEEDR, GPIOx->OTYPER, GPIOx->PUPDR
@fn    void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct)
@param GPIOG, GPIO_Pin_5, GPIO_Pin_6, GPIO_Mode_AF, GPIO_Speed_50MHz, GPIO_OType_PP, GPIO_PuPd_UP
@ref   stm32f2xx.h, stm32f2xx_gpio.h
*/