STM32 RTC alarm interrupt and wake-up standby mode

Publisher:meilidaowlLatest update time:2018-12-26 Source: eefocusKeywords:STM32  RTC Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

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.

Keywords:STM32  RTC Reference address:STM32 RTC alarm interrupt and wake-up standby mode

Previous article:STM32 RTC reading and writing incorrectly
Next article:STM32F1RCC clock configuration summary

Recommended ReadingLatest update time:2024-11-16 15:03

STM32 printf semihost mode
After reading the problem of printf function redirection in the usart section of Atom Brother, I tried it myself. The microcontroller can print information through the serial port, and the printf function is very convenient to use after redirection. Redirection refers to modifying the underlying function of printf s
[Microcontroller]
STM32 printf semihost mode
STMicroelectronics releases security software to protect STM32 edge AI devices connected to AWS IoT Core
New developer software for STM32H5 simplifies secure connections between IoT devices and AWS using ST’s Secure Manager software October 10, 2023, China - STMicroelectronics (STMicroelectronics), a world-leading semiconductor company serving multiple electronic applications, recently ad
[Embedded]
STMicroelectronics releases security software to protect STM32 edge AI devices connected to AWS IoT Core
STM32 peripheral structure definition and clock initialization statement sequence lead to compilation
1. When writing the peripheral initialization function, you need to define the structure of the peripheral and initialize the peripheral clock, etc. But today I accidentally wrote the code statements in reverse, and then the compilation failed, and the error message was: dac.c(41): error: #268: declaration may not app
[Microcontroller]
How to implement PWM waveform with adjustable frequency and duty cycle in STM32
Use two TIM timers: one outputs PWM with adjustable frequency and duty cycle, and the other counts (times) the output PWM pulses. 1. The gated method can be implemented, but it requires complex configuration and calculation, and is not recommended. 2. Pulse counting is a more practical and simpler method; There are se
[Microcontroller]
How to implement PWM waveform with adjustable frequency and duty cycle in STM32
【STM32】Basic principles of serial communication (super basic, detailed version)
STM32F1xx official information: "STM32 Chinese Reference Manual V10" - Chapter 25 Universal Synchronous Asynchronous Receiver Transmitter (USART)   Communication interface background knowledge How devices communicate with each other Generally speaking, the communication between devices can be divided into two ty
[Microcontroller]
【STM32】Basic principles of serial communication (super basic, detailed version)
STM32 IAP+APP Application
1. Before entering the topic, we first need to understand some necessary basic knowledge - the types and models of stm32 series chips:   startup_stm32f10x_cl.s Interconnect devices, STM32F105xx, STM32F107xx startup_stm32f10x_hd.s Large capacity STM32F101xx, STM32F102xx, STM32F103xx startup_stm32f10x_hd_vl.s Large capa
[Microcontroller]
STM32 IAP+APP Application
57. STM32 CAN controller principle and configuration
1. Introduction to STM32 CAN controller - bxCAN What is bxCAN: STM32 comes with a basic extended CAN peripheral, also known as bxCAN. The F103 has up to 14 filter banks, the F407 has 28. (II) Introduction to the modes of the STM32 CAN controller Working mode: It must be in initialization mode at the beginning to
[Microcontroller]
57. STM32 CAN controller principle and configuration
STM32 USB keyboard and mouse routine introduction
STM32 USB keyboard and mouse routines can be found on the Internet, but routines that integrate keyboard and mouse in the same device are relatively rare (I only found the 51+D12 version of Quanquan through GOOGLE). The following is a program for STM32 with integrated keyboard and mouse that I made with reference to
[Microcontroller]
Latest Microcontroller Articles
  • Download from the Internet--ARM Getting Started Notes
    A brief introduction: From today on, the ARM notebook of the rookie is open, and it can be regarded as a place to store these notes. Why publish it? Maybe you are interested in it. In fact, the reason for these notes is ...
  • Learn ARM development(22)
    Turning off and on interrupts Interrupts are an efficient dialogue mechanism, but sometimes you don't want to interrupt the program while it is running. For example, when you are printing something, the program suddenly interrupts and another ...
  • Learn ARM development(21)
    First, declare the task pointer, because it will be used later. Task pointer volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • Learn ARM development(20)
    With the previous Tick interrupt, the basic task switching conditions are ready. However, this "easterly" is also difficult to understand. Only through continuous practice can we understand it. ...
  • Learn ARM development(19)
    After many days of hard work, I finally got the interrupt working. But in order to allow RTOS to use timer interrupts, what kind of interrupts can be implemented in S3C44B0? There are two methods in S3C44B0. ...
  • Learn ARM development(14)
  • Learn ARM development(15)
  • Learn ARM development(16)
  • Learn ARM development(17)
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号