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

Viewed 10

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.

0 Answers
Related