cancel
Showing results for 
Search instead for 
Did you mean: 

How can I toggle an LED at 5th second of each minute with RTC Alarm?

akoluacik
Senior

I am working STM32F746-Disco Board, and trying to implement an Alarm in register level. I am trying to implement a system such that it toggles the user led at 5th second of each minute. However, my program toggles differentially. For now, I can notice that it toggles for 2 seconds, but I don't know at which second, or minute?

My codes are below:

RTC_Utils.c

/*
 * RTC_Utils.c
 *
 *  Created on: Sep 8, 2022
 */
 
 
#include "RTC_utils.h"
#include "stm32f746xx.h"
 
 
void RTC_Init(void) {
 
    uint32_t readBit;
 
//  __HAL_RCC_RTC_ENABLE();
    // Enable write access to the backup domain
    if(((RCC->APB1ENR) & (1U << 28)) == 0) {
        // Enable power interface clock
        RCC->APB1ENR |= (1U << 28);
 
        readBit = RCC->APB1ENR;
        //UNUSED(readBit);
    }
 
    // Select LSE as RTC clock source
    if(((PWR->CR1) & (1U << 8)) == 0) {
        PWR->CR1 |= (1U << 8);
        // Wait until the backup domain write protection has been disabled
        while(((PWR->CR1) & (1U << 8)) == 0);
    }
 
    // Reset LSEON and LSEBY before configuring
    RCC->BDCR &= ~((1U << 0) | (1U << 2));
 
    RCC->BDCR |= (1U << 16);
    RCC->BDCR &= ~(1U << 16);
 
    // Wait until LSE clock is ready
//  while(((RCC->BDCR) & (1U << 1)) == 0);
 
    RCC->BDCR |= (1U << 0);
 
    // Select LSE as RTC clock source
    RCC->BDCR |= 1U << 8;
    RCC->BDCR &= ~(1U << 9);
 
    // Disable power interface clock
    RCC->APB1ENR &= ~(1U << 28);
 
    RCC->BDCR |= 1U << 15;
 
    // Remove Write Protection
    RTC->WPR = 0xCA;
    RTC->WPR = 0x53;
 
    // Set INIT bit to 1 in the RTC_ISR register to enter initialization mode
    RTC->ISR |= 1U << 7;
 
    // Poll INITF bit of in the RTC_ISR register
    while((RTC->ISR & (1U << 6)) == 0);
 
    RTC->CR &= (1U << 6);
 
    // program both the prescaler factors to generate 1 Hz clock
    RTC->PRER |= ((2U << 7) - 1) << 16;
    RTC->PRER |= (2U << 8) - 1;
 
    // Load the initial time and date values in the shadow registers
    RTC->TR |= (1U << 22) | (1U << 21) | (8U << 16) | (4U << 12) | (5U << 8);
    RTC->DR |= (2U << 20) | (2U << 16) | (5U << 13) | (0U << 12) | (9U << 8) | (0U << 4) || (8U << 0);
 
    // configure the time format (12 or 24 hours)
    RTC->CR &= ~(1U << 6);
 
    // Disable Initialization
    RTC->ISR &= ~(1U << 7);
 
    // Enable WPR
    RTC->WPR = 0xFF;
}
 
void RTC_Set_Alarm(void) {
 
    RTC->WPR = 0xCA;
    RTC->WPR = 0x53;
 
    // Clear ALRAE in RTC_CR to disable Alarm A
    RTC->CR &= ~(1U << 8);
 
    // Set off alarm A if the second is 5
    RTC->ALRMAR |= 0x5;
 
    // Program the Alarm A registers (RTC_ALRMASSR/RTC_ALRMAR).
    // Mask every second option
    RTC->ALRMAR |= (1U << 23) | (1U << 15) | (1U << 31);
    RTC->ALRMAR &= ~(1U << 7);
 
    RTC->CR |= (1U << 8);
    RTC->CR |= 1U << 12;
 
    RTC->WPR = 0xFF;
}
 
void RTC_Alarm_Enable(void) {
    RTC_Init();
    RTC_Set_Alarm();
    // Configure EXTI17
    // Select Triggering Edge
    EXTI -> RTSR |= EXTI_RTSR_TR17;
 
    // Interrupt Mask Register
    EXTI -> IMR |= EXTI_IMR_IM17;
 
    // Event Mask Register
    EXTI -> EMR |= EXTI_EMR_EM17;
 
    // Interrupt Pending Register
    EXTI -> PR |= EXTI_PR_PR17;
 
    // Set It Priority Most Urgent
    NVIC_EnableIRQ(RTC_Alarm_IRQn);
    NVIC_SetPriority(RTC_Alarm_IRQn, 0);
}
 
void RTC_Alarm_IRQHandler(void) {
    if (RTC->ISR & (1U << 8)) {
        GPIOI->ODR ^= (1U << 1);
        RTC->ISR &= ~(1U << 8); // Clear the flag
    }
    EXTI -> PR |= EXTI_PR_PR17; // Clear pending interrupt flag
}

What is wrong with my code and what to do to toggle led at the 5th second of each minute? Furthermore, I have some doubts about RTC->TR and RTC->DR registers. What happened if I don't make any adjustments on them and how do they work? When and why we should use them? Thx in advance for your response.

11 REPLIES 11
MM..1
Chief II

Maybe better is ask, what you need? 5s toggle LED or RTC Alarm.

5s toggle LED can be more effective handled with PWM TIM = complete MCU offload = no one instruction after start required.

2U << 7 = 256

2U << 8 = 512

32768Hz / (256 * 512) = 0.25Hz

I don't think this is what you wanted.

It's in fact 0.5Hz, because the asynchronous prescaler has only 7 bits.

JW