Creating delay using Timer Interrupt | configuring RCC clock | STM32F103C8T6 | Arm Cortex M3

For a detailed Timer configuration, refer previous post

Program:

 /***************

Blinking LED connected to PC13 with interrupt created using Timer 2

SysClk = 72 MHz
Prescaler = 10000
f = 72000000 / 10000 = 7200 Hz clock for Timer 2
Auto_reloader = 36000

so, Timer counts till: 1 / f * Auto_reload
= 1 / 7200 * 36000 = 5 sec

****************/

#include "stm32f10x.h"
void TIM2_IRQHandler(void);
void RCC_config(void);

void RCC_config() // RCC clock configuration
{
  RCC -> CR |= RCC_CR_HSEON;                               // HSE ON
  RCC -> CFGR |= (RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL9);    
// Setting PLL - HSE * 9
  RCC -> CFGR |= RCC_CFGR_SW_1;                            // SysClk = PLLCLK
  RCC -> CR |= RCC_CR_PLLON;          
  // Turn ON PLL after above PLL configurations, making SysClk = HSE * 9 = 8 * 9 = 72 MHz
RCC -> CFGR |= RCC_CFGR_PPRE1_DIV2;
// APB1 = AHB / 2 = 72 / 2 = 36 MHz (max)
}

void TIM2_IRQHandler()
{
  TIM2 -> SR &= ~TIM_SR_UIF;            // UIF - clear timer interrupt flag
  GPIOC -> ODR ^= GPIO_ODR_ODR13;       // Toggle PC13 LED pin
}

int main()
{
  RCC_config();

  /* Port C - pin 13 settings for LED*/
 
  RCC -> APB2ENR |= RCC_APB2ENR_IOPCEN;     // Enable PortC Clock
 
  /* Select PortC_Pin 13 as output @2MHZ
   * Configure Pin 13 with open-drain */
 
  GPIOC -> CRH |= GPIO_CRH_MODE13_1 | GPIO_CRH_CNF13_0;
  GPIOC -> BSRR = GPIO_BSRR_BS13;         // Initialize PC13 LED - OFF
 
  /* Timer 2 settings
     TIM2 -> CR1 &= ~ TIM_CR1_DIR  - by default - UP counter */
 
  RCC -> APB1ENR |= RCC_APB1ENR_TIM2EN;  // Enable clock for Timer 2
  TIM2 -> CR1 &= ~TIM_CR1_CEN;           // CEN = 0 - Counter disable
  TIM2 -> PSC = (10000 - 1);             // Prescaler
  TIM2 -> ARR = 36000;                    // Auto reload value - counts upto 5 sec
 
  NVIC_EnableIRQ(TIM2_IRQn);             // Enable specific interrupt in NVIC
  TIM2 -> DIER |= TIM_DIER_UIE;          // Timer interrupt enable
 
  TIM2 -> CNT = 0;                       // Counter initialized to 0    
  TIM2 -> CR1 |= TIM_CR1_CEN;            // CEN = 1 - Counter enable
 
  while(1)
  {
    // Do nothing  
  }
  return 0;
}

Timer Interrupt:

Get the ISR name from Startup code in KEIL or just add _IRQHandler to the peripheral name to get the interrupt function name.

In STM32, the respective interrupt (IRQ - Interrupt Request) should be enabled in NVIC (Nested Vectored Interrupt Controller) -> NVIC_EnableIRQ()

To create PWM using Timer, see next post

Comments