Skip to main content
Associate II
June 2, 2021
Solved

STM32F103C8 RTC SECIE: cannot enter interrupt handler

  • June 2, 2021
  • 2 replies
  • 1139 views

I'm trying to blink a LED once per second, using the SEC interrupt.

I'm rewriting a NIXIE clock I wrote, that used a home-brewed dly() function, so the remnants of that code are still there, sorry about that.

According to Ref Manual I have, if the SECIE bit is set, I should enter the RTC_IRQ.

My code reads as follows:

#include <stm32f10x.h>
 
//__iar_program_start
volatile unsigned int clckH=0;
volatile unsigned int clckM=0;
volatile unsigned int LED_Status=0; //Status of LED connected to PC_13
volatile unsigned int BNRY_CNTR=0; //Counter for Nixie prototype test
 
void delay(long dly)
{
 int cntr = RTC->CNTL;
 for(int i=cntr;i<(cntr+dly);i++);
}
 
void PLLEnable(void)
{
 RCC->CR |= RCC_CR_HSEON;
 while(!(RCC->CR & RCC_CR_HSERDY));
 
 RCC->CFGR |= RCC_CFGR_SW_HSE;
 RCC->CR &= ~RCC_CR_HSION;
 
 RCC->CFGR |= RCC_CFGR_PLLMULL9;
 RCC->CFGR |= RCC_CFGR_PLLSRC;
 
 FLASH->ACR |= 18; //Enable FLash Prefetch due to high PLL speed.
 
 RCC->CR |= RCC_CR_PLLON;
 while(!RCC->CR & RCC_CR_PLLRDY);
 
 RCC->CFGR &= ~RCC_CFGR_SW_HSE;
 RCC->CFGR |= RCC_CFGR_SW_PLL;
 while(!(RCC->CFGR & RCC_CFGR_SWS_1));
}
 
void RunRealTimeClock(void)
{
 RCC->APB1ENR |= 0x18000000; //Set PWREN and BKPEN bits
 //This enables Power Clock and Allows access to Backup domain
 
 if(!(RCC->BDCR &2)) //Check if the low speed external (LSE) oscillator is already on
 {
 PWR->CR |= 0X00000100; //Enable backup domain editing (set DPB)
 RCC->BDCR |= 0x00000001; //Enable LSE
 while(!(RCC->BDCR & 2)); //Wait for LSE to come online
 RCC->BDCR |= 0x00000100; //Set LSE as RTC clock
 }
 RCC->BDCR |= 0x00008000; //Enable RTC
 while(!(RTC_CRL_RSF)); //Wait for RTC registers to syncronize
 while(!(RTC_CRL_RTOFF)); //Wait for RTC registers to finish setting
 RTC->CRH |= RTC_CRH_SECIE; //Enable only 1_SECOND_INTERRUPT
 while(!(RTC_CRL_RTOFF)); //Wait for RTC registers to finish setting
 RTC->CRL |= 0x0010; //Enable RTC configuring
 RTC->PRLH = 0X000F; //Set the divider to 32767
 RTC->PRLL = 0XFFFF; //Set the divider to 32767
 RTC->CRL &= 0xFFFFFFEF; //Disable RTC configuring
 while(!(RTC_CRL_RTOFF)); //Wait for RTC registers to finish setting
 RCC->APB1ENR |= 0; //Should not be here
 
 #ifndef RCC_CSR_LSIRDY
 #define RCC_CSR_LSIRDY 1<<1;
 #endif
 RCC->CSR |= 1;
 while (!(RCC->CSR & 2)); //Wait for LSI (internal low speed OSC) to be ready
}
 
void EnableGPIOB()
{
#ifndef FullClock //If there is only one IN-17
 unsigned int crl_sts=GPIOB->CRL;
 unsigned int crh_sts=GPIOB->CRH;
 crl_sts=crl_sts&0xFF000000;
 crh_sts=crh_sts&0x000000FF;
 if((crl_sts != 0x66000000)&(crh_sts != 0x00000066))
 {
 RCC->APB2ENR |= 0x00000008; //Enable PortB Clock
 GPIOB->CRL &= 0x66FFFFFF;
 GPIOB->CRL |= 0x66000000; //Set PB_6-7 to GPO Open Drain, 2Mhz Output
 GPIOB->CRH &= 0xFFFFFF66;
 GPIOB->CRH |= 0x00000066; //Set PB_8-9 to GPO Open Drain, 2Mhz Output
 }
#else
 //Add B12-15 as outputs
 unsigned int crl_sts=GPIOB->CRL;
 unsigned int crh_sts=GPIOB->CRH;
 crl_sts=crl_sts&0xFF000000;
 crh_sts=crh_sts&0xFFFF00FF;
 if((crl_sts != 0x66000000)&(crh_sts != 0x66660066))
 {
 RCC->APB2ENR |= 0x00000008; //Enable PortB Clock
 GPIOB->CRL &= 0x66FFFFFF;
 GPIOB->CRL |= 0x66000000; //Set PB_6-7 to GPO Open Drain, 2Mhz Output
 GPIOB->CRH &= 0x6666FF66;
 GPIOB->CRH |= 0x66660066; //Set PB_8-9 to GPO Open Drain, 2Mhz Output
 }
#endif
}
 
void OutputCounter()
{
 unsigned int tmp=BNRY_CNTR;
 EnableGPIOB();
 tmp = tmp<<6;
 GPIOB->ODR &= 0xFC3F; // 0b1111110000111111;
 GPIOB->ODR |=tmp;
 BNRY_CNTR++;
 if(BNRY_CNTR >= 10) BNRY_CNTR=0;
}
 
/*------------------------------------------
Toggles the PC13 GPIO, which is the LED on the BluePill
If called with value, calls the delay function
If 0 value is sent, ignores Delay function
 
The latter for possible use with interrupts, which I have no idea how to address.
------------------------------------------*/
void LED_Toggle(unsigned int dly)
{
 if(LED_Status)
 {
 GPIOC->BSRR= GPIOC->BSRR | 0x00002000; //Reset pin PC13 (LED on BluePill)
 LED_Status = 0;
 OutputCounter();
 }
 else
 {
 GPIOC->BSRR= GPIOC->BSRR | 0x20000000; //Set pin PC13 (LED on BluePill)
 LED_Status = 1;
 }
 if(dly) delay(dly);
}
 
void RTC_IRQHandler(void)
{
 __disable_irq(); //Disable IRQs
 RTC->CRL&=0xFFFFFFFE; //Lower RTC_IRQ_SECF flag
 LED_Toggle(0000000); //Call LED Toggle Procedure
 __enable_irq(); //Enable IRQs
}
 
int main()
{
 __disable_irq();
 PLLEnable();
 RunRealTimeClock();
 RTC->CRL&=0xFFFFFFFE;
 int RealTime = RTC->CNTL;
 RCC->APB2ENR |= 0x00000010; //Enable PortC clock
 GPIOC->CRH |= 0x00500000; //Setting CNF13 to 01 (GPO, Open Drain) and Mode13 to 10 MHz Output.
 __enable_irq();
 while(1);
}

But I don't get to the RTC_IRQHandler() function for some reason.

Can anyone help me?

This topic has been closed for replies.
Best answer by TDK

In addition to setting the IE bit, you need to enable the interrupt using NVIC_EnableIRQ.

2 replies

TDK
TDKBest answer
June 2, 2021

In addition to setting the IE bit, you need to enable the interrupt using NVIC_EnableIRQ.

"If you feel a post has answered your question, please click ""Accept as Solution""."
BGor.1Author
Associate II
June 2, 2021

Awesome!

Thank you for answering!

I haven't seen it mentioned in the documentation.

I'll check it out.