STM32 timer interrupt does not work

There is an stm32f103c8 microcontroller on a Chinese debug board. I want to flash the LED with a frequency of 1 Hz through the timer interrupt, but for some reason it does not work. Here is the code:

#include "stm32f10x.h"
bool i=0;
int main(void){
RCC->CR |= RCC_CR_HSEON; // Запустить HSE
while((RCC->CR & RCC_CR_HSERDY) == 0); // Ожидание готовности HSE
RCC->CFGR |= RCC_CFGR_HPRE_DIV1 | RCC_CFGR_PPRE2_DIV1 | RCC_CFGR_PPRE1_DIV1 | (1<<10); // HCLK = SYSCLK ;  PCLK2 = HCLK ; PCLK1 = HCLK ; ABP1 = 72000000 : 2
RCC->CFGR &= ~((RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL)); // Предочистка
RCC->CFGR |= RCC_CFGR_PLLSRC_HSE; // Тактировать PLL от HSE (8 MHz)
RCC->CFGR |= RCC_CFGR_PLLMULL9; // Умножать частоту на 9 (8*9=72 MHz)
RCC->CR |= RCC_CR_PLLON; // Запустить PLL
while((RCC->CR & RCC_CR_PLLRDY) == 0); // Ожидание готовности PLL
RCC->CFGR &= ~RCC_CFGR_SW; // Очистить биты SW0, SW1
RCC->CFGR |= RCC_CFGR_SW_PLL; // Тактирование с выхода PLL
while((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_1); // Ожидание переключения на PLL

FLASH->ACR |= FLASH_ACR_PRFTBE; // Включить Prefetch Buffer
FLASH->ACR &= ~(FLASH_ACR_LATENCY); // Предочистка
FLASH->ACR |= FLASH_ACR_LATENCY_2;

RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;
RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;

asm("NOP");//подождать при смене тактирования
asm("NOP");
asm("NOP");
asm("NOP");

GPIOA->CRL = 0;
GPIOA->CRH = 0;
GPIOA->ODR = 0;
GPIOA->CRL |= (1<<4); //A1 выход 10 MHz
GPIOA->BSRR |= (1<<1); //подать напряжение на пин A1

TIM2->PSC = 36000000 / 1000 - 1; //пределитель 36000
TIM2->ARR = 1000;
TIM2->DIER |= TIM_DIER_UIE;//вкл прерывание таймера
NVIC_EnableIRQ(TIM2_IRQn);//разр прерывание таймера
__enable_irq();//вкл прерывания
TIM2->CR1 |= TIM_CR1_CEN; //запустить таймер
while(1)
{

}
}//main

void TIM2_IRQHandler(void){
TIM2->SR &= ~TIM_SR_UIF;//очистить флаг прерывания
if (i == 1) {
    GPIOA->BSRR = (1<<1);
} 
else {
    GPIOA->BSRR = (1<<17);
}
i = !i;
}//TIM2_IRQHandler

I'm using eclipce with the GNU ARM plugin. I want to understand my mistake. Thanks for your attention!

Code after the solution:

#include "stm32f10x.h"
#if 0
  #include "stm32f10x_gpio.h"
#endif
uint8_t x = 0;
bool i = 0;
int main(void)
{

  RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;//включить GPIOA
  RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;//включить TIM2

  RCC->CR |= RCC_CR_HSEON; // Запустить HSE
  while((RCC->CR & RCC_CR_HSERDY) == 0); // Ожидание готовности HSE
  RCC->CFGR |= RCC_CFGR_HPRE_DIV1 | RCC_CFGR_PPRE2_DIV1 | RCC_CFGR_PPRE1_DIV1 | (1<<10); // HCLK = SYSCLK ;  PCLK2 = HCLK ; PCLK1 = HCLK
  RCC->CFGR &= ~((RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL)); // Предочистка
  RCC->CFGR |= RCC_CFGR_PLLSRC_HSE; // Тактировать PLL от HSE (8 MHz)
  RCC->CFGR |= RCC_CFGR_PLLMULL9; // Умножать частоту на 9 (8*9=72 MHz)
  RCC->CR |= RCC_CR_PLLON; // Запустить PLL
  while((RCC->CR & RCC_CR_PLLRDY) == 0); // Ожидание готовности PLL
  RCC->CFGR &= ~RCC_CFGR_SW; // Очистить биты SW0, SW1
  RCC->CFGR |= RCC_CFGR_SW_PLL; // Тактирование с выхода PLL
  while((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_1); // Ожидание переключения на PLL

  FLASH->ACR |= FLASH_ACR_PRFTBE; // Включить Prefetch Buffer
  FLASH->ACR &= ~(FLASH_ACR_LATENCY); // Предочистка
  FLASH->ACR |= FLASH_ACR_LATENCY_2;

  for(x = 0; x <= 32; x++) asm("NOP");//подождать при смене тактирования


  GPIOA->CRL = 0;
  GPIOA->CRH = 0;
  GPIOA->ODR = 0;
  GPIOA->CRL |= (1<<4); //A1 выход 10 MHz
  GPIOA->BSRR |= (1<<1); //подать напряжение на пин A1

  TIM2->PSC = 36000000 / 1000 - 1; //пределитель 36000
  TIM2->ARR = 1000;
  TIM2->DIER |= TIM_DIER_UIE;//вкл прерывание таймера
  NVIC_EnableIRQ(TIM2_IRQn);//разр прерывание таймера
  __enable_irq();//вкл прерывания
  TIM2->CR1 |= TIM_CR1_CEN; //запустить таймер
  while(1)
  {
    asm("NOP");
  }
}

extern "C"
{
  void TIM2_IRQHandler(void)
  {
    TIM2->SR &= ~TIM_SR_UIF;//очистить флаг прерывания
    if (i == 1) 
    {
      GPIOA->BSRR = (1<<1);
    }
    else 
    {
      GPIOA->BSRR = (1<<17);
    }
    i = !i;
  }
}
Author: Caricardo137, 2018-03-10

1 answers

It turned out that you need to link interrupts and header files via extern "C", if you use cpr.

 1
Author: Caricardo137, 2018-03-12 18:52:07