2021-06-02 12:25 AM
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?
Solved! Go to Solution.
2021-06-02 06:35 AM
In addition to setting the IE bit, you need to enable the interrupt using NVIC_EnableIRQ.
2021-06-02 06:35 AM
In addition to setting the IE bit, you need to enable the interrupt using NVIC_EnableIRQ.
2021-06-02 06:43 AM
Awesome!
Thank you for answering!
I haven't seen it mentioned in the documentation.
I'll check it out.