Skip to main content
Associate II
Jun 2, 2021 7:25 AM UTC
Solved

STM32F103C8 RTC SECIE: cannot enter interrupt handler

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.
TDK
TDKBest answer
Jun 2, 2021 1:35 PM UTC

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""."

2 replies

TDK
TDKBest answer
Jun 2, 2021 1:35 PM UTC

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
Jun 2, 2021 1:43 PM UTC

Awesome!

Thank you for answering!

I haven't seen it mentioned in the documentation.

I'll check it out.