RTC stands for real-time clock. It has many uses because it provides a relatively accurate clock reference. This article mainly explains the RTC alarm interrupt function based on STM32F103 and how to wake up the STM32 standby mode using the alarm interrupt.
There are several key points to note about RTC: 1. After the RTC value is set, it will continue to increment according to the set reference time. If you find a button battery on your hardware device, it is used to power the RTC function. Therefore, even if the main power of the device is turned off, the operation of the RTC will not be affected. Of course, if the button battery is removed or it is not used, it will not work. 2. After each STM32 reset, the RTC value should be considered whether it will restart or continue to count. 3. The RTC value has an upper limit, and its maximum value is 2 to the power of 32 minus 1. This number is very large, so don't worry too much.
The first example in this article is to set the RTC to increment by one unit per second, trigger an alarm and enter an interrupt every 40 seconds, and output the seconds to the computer every second. The following is the initialization configuration of the RTC. (The first program is modified from the program of the punctual atom)
u8 RTC_Init()
{
u8 temp = 0;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_BKP|RCC_APB1Periph_PWR,ENABLE); //Power clock and back clock
PWR_BackupAccessCmd(ENABLE); //Allow back area writing
if (BKP_ReadBackupRegister(BKP_DR1) != 0xC0B4)
{
BKP_DeInit();
RCC_LSEConfig(RCC_LSE_ON);
while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)
{
temp++;
delay_ms(10);
}
if(temp>=250)return 1;
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
RCC_RTCCLKCmd(ENABLE);
RTC_WaitForLastTask();
RTC_WaitForSynchro();
RTC_ITConfig(RTC_IT_SEC|RTC_IT_ALR, ENABLE); //Enable the RTC second interrupt and alarm interrupt
RTC_WaitForLastTask();
RTC_EnterConfigMode(); //Enter configuration RTC mode
RTC_SetPrescaler(32767);
RTC_SetCounter(0); //The initial value is set to 0s
RTC_WaitForLastTask();
RTC_SetAlarm(40); //Set the alarm value to 40s
RTC_WaitForLastTask(); //Wait for the above configuration to complete
RTC_ExitConfigMode(); //Exit configuration mode
BKP_WriteBackupRegister(BKP_DR1, 0XC0B4);
PWR_BackupAccessCmd(DISABLE); //Do not allow back area write operation
}
else
{
PWR_BackupAccessCmd(DISABLE);
RTC_WaitForSynchro();
RTC_ITConfig(RTC_IT_SEC|RTC_IT_ALR,ENABLE); //Enable the RTC second interrupt and alarm interrupt
RTC_WaitForLastTask();
}
NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn; //RTC global interrupt interrupt configuration
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
return 0;
}
//Usage of this initialization function in the main function
while(RTC_Init())
{
printf("INIT Programing is ERROR!!\r\n");
}
if (BKP_ReadBackupRegister(BKP_DR1) != 0xC0B4) means to let STM32 self-check after power on whether it is the first time to run this program. BKP_ReadBackupRegister(BKP_DR1) means reading the value of BKP_DR1. If it is the first time to run this program, the value must be 0X0000. If the value is not equal to 0XC0B4, it will enter the configuration initialization program. BKP_WriteBackupRegister(BKP_DR1, 0XC0B4) means writing 0XC0B4 to the BKP_DR1 register. Note that after the value of BKP_DR1 is written, it will not be cleared to 0000 even if it is reset. In this case, even if it is reset or powered on again, the initial program will not be executed again, so the value of RTC will not be reset. If you want the RTC value to count from 0 again, you can change 0XC0B4 to a new number and download the program again.
The next clock configuration is to turn on the external low-speed clock LSE, which provides the clock frequency to the RTC. Its frequency is 32.768KHZ. We need to use it after dividing it into 1HZ.
According to the above figure, 1HZ = 32768/(32767+1), so you can understand what RTC_SetPrescaler(32767) means.
There are still two options for providing clock frequency for RTC, and one is enough for us here.
RTC_WaitForLastTask() and RTC_WaitForSynchro() both mean waiting for the most recent write operation to complete. These two, especially the first one, are very important when configuring the RTC. If they are added to the wrong location or are missing, the program will sometimes get stuck in one place.
Next, turn on the RTC second interrupt and alarm interrupt. Next, configure some specific RTC settings, such as the initial value, counting frequency, and alarm value. According to ST:
You need to use the three library functions RTC_WaitForLastTask(), RTC_EnterConfigMode (enter configuration) and RTC_ExitConfigMode (exit configuration).
Finally, write 0XC0B4 to the BKP_DR1 register to indicate that the first RTC configuration is complete. When the program is reset or the device is powered on again, it will not enter this configuration program again. Also turn off the write operation enable bit of the back register.
The else program is the command executed when the program is run for the second time. It mainly turns on the two interrupts of RTC.
The next step is to configure the RTC global interrupt. This interrupt includes the alarm and second interrupts. There is also a return value that can only be understood in the main program. Simply put, a return of 0 means that there is no problem with the RTC configuration, and a return of 1 means the opposite. You don't need to use the return value method because it is generally OK.
The following is an introduction to the RTC global interrupt:
void RTC_IRQHandler()
{
if(RTC_GetITStatus(RTC_IT_ALR)!=RESET) //Whether the alarm interrupt occurs
{
printf("THE ALARM READY =%d \r\n",RTC_GetCounter());//Output the number of seconds at this time
RTC_ClearITPendingBit(RTC_IT_ALR);
PWR_BackupAccessCmd(ENABLE);
RTC_EnterConfigMode();
RTC_WaitForLastTask();
RTC_SetAlarm(40+RTC_GetCounter()); //Configure the next alarm to be set after 40 seconds
RTC_WaitForLastTask();
RTC_ExitConfigMode();
PWR_BackupAccessCmd(DISABLE);
}
if(RTC_GetITStatus(RTC_IT_SEC)!=RESET) //Whether the second interrupt occurs
{
printf("Time is =%d \r\n",RTC_GetCounter()); //Output the seconds at this time
}
RTC_ClearITPendingBit(RTC_IT_SEC|RTC_IT_OW); //Clear the second interrupt flag and overflow bit
RTC_WaitForLastTask();
}
The following is the result of running the program.
One thing to note is that if you write the function for judging the second interrupt before the function for judging the alarm interrupt in the interrupt function, you will get THE ALARM READY=41. Another point is that even if you don’t write it in reverse, the next alarm time will be 81 seconds, as shown in the figure
The following is the standby wake-up:
Standby mode is the lowest power mode. External reset (NRST pin), IWDG reset, rising edge on WKUP pin or RTC alarm event
When it happens, STM32 exits from standby mode. The external reset and WKUP methods are relatively simple. We will mainly talk about RTC alarm wake-up.
One of these two programs connects a pin of STM32 to a button. When the button is pressed, STM32 enters standby mode, and wakes up STM32 when the 40-second alarm comes.
The other is to enter standby mode when a button is pressed, and the alarm is set to 5 seconds later, and the STM32 will wake up when the alarm comes.
void RTC_Init()
{
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_BKP|RCC_APB1Periph_PWR,ENABLE);
PWR_WakeUpPinCmd(ENABLE);
PWR_BackupAccessCmd(ENABLE);
BKP_DeInit();
RCC_LSEConfig(RCC_LSE_ON);
while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)
{
}
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
RCC_RTCCLKCmd(ENABLE);
RTC_WaitForLastTask();
RTC_WaitForSynchro();
RTC_ITConfig(RTC_IT_SEC, ENABLE);
RTC_WaitForLastTask();
RTC_EnterConfigMode();
RTC_SetCounter(0); //Set the initial count value
RTC_WaitForLastTask();
RTC_SetPrescaler(32767);
RTC_WaitForLastTask();
RTC_SetAlarm(40); //Alarm timer 40S
RTC_WaitForLastTask();
RTC_ExitConfigMode();
NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn; //RTC global interrupt, its priority is lower than the key
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
void EXTIX_Init(void)
{
EXTI_InitTypeDef EXTI_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOC,ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOC,GPIO_PinSource5); //Configure button PC5 as external interrupt
EXTI_InitStructure.EXTI_Line=EXTI_Line5;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn; //The priority of external interrupt is higher than RTC
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
void EXTI9_5_IRQHandler() //External interrupt corresponding to the button
{
EXTI_ClearITPendingBit(EXTI_Line5);
PWR_EnterSTANDBYMode(); //Enter standby mode
}
void RTC_IRQHandler() //RTC interrupt
{
if(RTC_GetITStatus(RTC_IT_SEC)!=RESET)
{
printf("TIME IS =%d \r\n",RTC_GetCounter());
}
RTC_ClearITPendingBit(RTC_IT_SEC|RTC_IT_OW);
RTC_WaitForLastTask();
}
The above routine is to make the STM32 display the time on the computer every second in the running mode. After pressing the button connected to PC5, the STM32 enters the standby mode. After 40 seconds, the alarm is triggered and the STM32 exits the standby mode. It should be noted that this program does not set the RTC value to be saved, so the time starts from zero every time after exiting the standby mode. And the button triggering the standby mode must be before the STM32 is powered on for 40 seconds, otherwise the alarm will be missed after 40 seconds and the STM32 cannot be woken up.
When the button is pressed at 13 seconds and the count reaches 40 seconds, the STM32 serial port cannot send data. When the 40s alarm comes, the count starts from 0 again, and exiting the standby mode is equivalent to resetting.
The second example program enters standby mode when the key is pressed. The alarm is set to 5 seconds later. When the alarm rings, it wakes up the STM32. When running, the seconds are displayed to the computer. This program can be modified in a few places on the above one.
void RTC_Init()
{
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_BKP|RCC_APB1Periph_PWR,ENABLE);
PWR_WakeUpPinCmd(ENABLE);
PWR_BackupAccessCmd(ENABLE);
if(PWR_GetFlagStatus(PWR_FLAG_SB)!=RESET) //If it is in standby mode
{
PWR_ClearFlag(PWR_FLAG_SB); //Clear standby mode
RTC_ITConfig(RTC_IT_SEC, ENABLE); //Enable RTC interrupt
RTC_WaitForSynchro();
}
else
{
BKP_DeInit();
RCC_LSEConfig(RCC_LSE_ON);
while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)
{
}
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
RCC_RTCCLKCmd(ENABLE);
RTC_WaitForLastTask();
RTC_WaitForSynchro();
RTC_ITConfig(RTC_IT_SEC, ENABLE);
RTC_WaitForLastTask();
RTC_EnterConfigMode();
RTC_SetCounter(0);
RTC_WaitForLastTask();
RTC_SetPrescaler(32767);
RTC_WaitForLastTask();
//RTC_SetAlarm(35); //Cancel this alarm setting
RTC_WaitForLastTask();
RTC_ExitConfigMode();
}
NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
void EXTI9_5_IRQHandler()
{
EXTI_ClearITPendingBit(EXTI_Line5);
RTC_ClearFlag(RTC_FLAG_SEC);
while(RTC_GetFlagStatus(RTC_FLAG_SEC)==RESET);
RTC_SetAlarm(RTC_GetCounter()+5); //Alarm adds 5 seconds to this time
RTC_WaitForLastTask();
PWR_EnterSTANDBYMode(); //Enter standby mode
}
No other changes are required.
The running results of this program show that it enters standby mode for 5 seconds at 450 seconds and then continues to run.
Time does not start at 0.
Previous article:STM32 RTC reading and writing incorrectly
Next article:STM32F1RCC clock configuration summary
Recommended ReadingLatest update time:2024-11-16 15:03
- Popular Resources
- Popular amplifiers
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- Innolux's intelligent steer-by-wire solution makes cars smarter and safer
- 8051 MCU - Parity Check
- How to efficiently balance the sensitivity of tactile sensing interfaces
- What should I do if the servo motor shakes? What causes the servo motor to shake quickly?
- 【Brushless Motor】Analysis of three-phase BLDC motor and sharing of two popular development boards
- Midea Industrial Technology's subsidiaries Clou Electronics and Hekang New Energy jointly appeared at the Munich Battery Energy Storage Exhibition and Solar Energy Exhibition
- Guoxin Sichen | Application of ferroelectric memory PB85RS2MC in power battery management, with a capacity of 2M
- Analysis of common faults of frequency converter
- In a head-on competition with Qualcomm, what kind of cockpit products has Intel come up with?
- Dalian Rongke's all-vanadium liquid flow battery energy storage equipment industrialization project has entered the sprint stage before production
- Allegro MicroSystems Introduces Advanced Magnetic and Inductive Position Sensing Solutions at Electronica 2024
- Car key in the left hand, liveness detection radar in the right hand, UWB is imperative for cars!
- After a decade of rapid development, domestic CIS has entered the market
- Aegis Dagger Battery + Thor EM-i Super Hybrid, Geely New Energy has thrown out two "king bombs"
- A brief discussion on functional safety - fault, error, and failure
- In the smart car 2.0 cycle, these core industry chains are facing major opportunities!
- The United States and Japan are developing new batteries. CATL faces challenges? How should China's new energy battery industry respond?
- Murata launches high-precision 6-axis inertial sensor for automobiles
- Ford patents pre-charge alarm to help save costs and respond to emergencies
- New real-time microcontroller system from Texas Instruments enables smarter processing in automotive and industrial applications
- EEWORLD University Hall----Intelligent Control System
- Body fat scale is broken, pry it open and see
- 【New Year's Festival Competition】+ "Big Head Doll" Amusement Park
- OLED Technology Consulting Part-time
- What issues should be paid attention to when developing 51 single-chip microcomputer operating system
- What are the advantages of Qorvo's Fusion 5G product portfolio, which won the "Global Electronics Achievement Award"?
- EEWORLD University ----TI DLP? Labs - Display
- Predictive Control Algorithm Program
- How to configure 2 network ports?
- Prize live broadcast: C-V2X (Internet of Vehicles) test challenges and solutions, make an appointment to win Keysight gifts