Cortex_m3_stm32 Embedded Learning Note (14): RTC Real-time clock (seconds interrupt)

Source: Internet
Author: User

the STM32 real-time Clock (RTC) is a stand-alone timer. The RTC module of the STM32 has a set of continuously counted counters, which, under the corresponding software configuration, provides the function of the clock calendar. Modifying the value of a counter can reset the time and date before the system.

Since the clock only needs to be configured once, the next time the power-on does not need to be reconfigured (the Development Board has a battery), so need to use the backup area (BKP) to mark whether the clock is configured

A brief introduction to BKP: The backup register is 42 16-bit registers (the Mini board is a large capacity) and can be used to store 84 bytes of user application data. They are in the backup domain, and when the VDD power is cut off, they are still powered by the VBAT. They are not reset even when the system is woken up in standby mode, or when the system is reset or the power is reset . In addition, the BKP control register is used to manage intrusion detection and RTC calibration functions.

Briefly, I understand how the clock works: A 32-bit counter, counting from 0, assuming that each plus one is 1 seconds, then a 32-bit counter runs to an overflow that takes more than 100 years. It's been a long time, and here the clock comes with a second interrupt, which triggers a second interrupt every time we add one, and we can achieve the effect of timing by writing the update time function to the second interrupt.

Because there are a lot of functions in RTC.C. I'll just post a few more important ones.


#include "rtc.h" _calendar_obj calendar;//clock structure const U8 Mon_table[12]={31,28,31,30,31,30,31,31,30,31,30,31};const U8 table_week[12]={0,3,3,6,1,4,6,2,5,0,3,5}; Monthly correction Data Sheet U8 Is_leapyear (U16 year) {return (year%4==0&&year%100!=0) | | year%400==0;} Get now is the day of the Week//Function Description: Enter the Gregorian calendar date to get the week (only 1901-2,099)//Input parameters: Gregorian calendar Month Day//return value: Weekday U8 Rtc_get_week (U16 year,u8 Month,u8 Day) {U16 Temp2; U8 yearh,yearl;yearh=year/100;yearl=year%100; If 21st century, the number of years in which the year is added if (yearh>19) yearl+=100;//is only calculated after 1900 years of temp2=yearl+yearl/4;temp2=temp2%7; Temp2=temp2+day+table_week[month-1];if (yearl%4==0&&month<3) Temp2--;return (temp2%7);} static void Rtc_nvic_config (void) {nvic_inittypedef nvic_initstructure; Nvic_initstructure.nvic_irqchannel = RTC_IRQN;//RTC Global Interrupt nvic_initstructure.nvic_irqchannelpreemptionpriority = 0;// Priority 1-bit, priority 3-bit nvic_initstructure.nvic_irqchannelsubpriority = 0;//First 0-bit priority, 4-bit nvic_initstructure.nvic_ from the priority level Irqchannelcmd = enable;//Enable the channel to interrupt Nvic_init (&nvic_initstructure);//Initialize peripheral nvic_initstruct registers according to parameters specified in NVIC}//gets the current time, the result is saved in the Calendar structure//return value: 0, success; other: Error code. U8 Rtc_get (void) {static U16 daycnt=0;u32 Timecount=rtc_getcounter ( ); u32 daynum=timecount/86400;u16 tem=0;if (daycnt!=daynum)//greater than 1 days {daycnt=daynum;tem=1970;while (daynum>=365) {if ( Is_leapyear (TEM)) {if (daynum>=366) Daynum-=366;else break;} else daynum-=365;tem++; }calendar.w_year=tem;//year Tem=0;while (daynum>=28) {if (Is_leapyear (calendar.w_year) &&tem==1) {if (daynum >=29) Daynum-=29;else break;} Else{if (Daynum>=mon_table[tem]) Daynum-=mon_table[tem];else break;} tem++;} calendar.w_month=tem+1;//month calendar.w_date=daynum+1;//Day} daynum=timecount%86400;calendar.hour=daynum/3600;// When calendar.min= (daynum%3600)/60;//cent calendar.sec= (daynum%3600)%60;//sec calendar.week=rtc_get_week (calendar.w_year,    Calendar.w_month,calendar.w_date); return 0;} Set the clock//convert the input clock to seconds//on January 1, 1970 as the benchmark//1970~2099 year for the legal year//return value: 0, success; other: Error code.//Common Year Month date table//year,mon,day,hour,min, SEC: Month Day time seconds//return value: Sets the result. 0, success, 1, failure. U8 Rtc_set (U16 year,u8 mon,u8 day,u8 hour,u8 min,u8 sec) {U16 I;uSeccnt=0;if (year<1970| | year>2099) return 1;for (i=1970;i<year;i++) {if (Is_leapyear (i)) Seccnt+=31622400;else seccnt+=31536000;} Mon-=1;for (i=0;i<mon;i++) {seccnt+= (u32) mon_table[i]*86400;if (is_leapyear (year) &&i==1) seccnt+=86400;} seccnt+= (U32) (day-1) *86400;seccnt+= (u32) hour*3600;seccnt+= (u32) min*60;seccnt+= (u32) sec;//enable PWR and BKP peripheral clocks rcc_ Apb1periphclockcmd (rcc_apb1periph_pwr|    RCC_APB1PERIPH_BKP, ENABLE); Pwr_backupaccesscmd (ENABLE);  Enable RTC and fallback register access to Rtc_setcounter (SECCNT);  Set the value of the RTC counter Rtc_waitforlasttask (); Wait for the last write to the RTC register to complete return 0;} Initialize RTCu8 rtc_init (void) {U8 tem=0;if (bkp_readbackupregister (BKP_DR1)!=0x5050)//if not configured {//enable PWR and BKP peripheral clocks rcc_ Apb1periphclockcmd (rcc_apb1periph_pwr|  RCC_APB1PERIPH_BKP, ENABLE); Pwr_backupaccesscmd (enable);//enable backup register access to Bkp_deinit ();//③ Reset Backup Area rcc_lseconfig (rcc_lse_on);//Set external low-speed crystal (LSE)// Checks whether the specified RCC flag bit is set or not, waits for low-speed crystal ready while (Rcc_getflagstatus (Rcc_flag_lserdy) ==reset) {tem++;d Elay_ms (10);} if (tem>=250) return 1;//initialization clock failed, Crystal has a problem rcc_rtcclkcoNfig (Rcc_rtcclksource_lse)///Set RTC Clock Rcc_rtcclkcmd (enable);//enable RTC clock Rtc_waitforlasttask ();//wait for last time to RTC The write operation of the Register completes Rtc_waitforsynchro ();//waits for the RTC Register to synchronize Rtc_itconfig (rtc_it_sec,enable);//enable RTC seconds Interrupt rtc_waitforlasttask ();  Wait for the most recent write operation to the RTC Register completed Rtc_setprescaler (32767); Set the value of the RTC prescaler Rtc_waitforlasttask (); Wait for the last write operation to the RTC register to complete rtc_set (2009,12,2,10,0,55);  Set time Rtc_exitconfigmode (); Exit configuration mode//write user program data to the specified fallback register 0x5050 bkp_writebackupregister (bkp_dr1,0x5050);} Else{rtc_waitforsynchro ()///wait for the last write operation to the RTC Register to complete rtc_itconfig (rtc_it_sec,enable);//enable RTC Interrupt Rtc_waitforlasttask (); Wait for the most recent write operation to the RTC register to complete}rtc_nvic_config (); RCT Interrupt grouping setting rtc_get (); Update time return 0; Ok}void Rtc_irqhandler (void) {if (Rtc_getitstatus (rtc_it_sec)!=reset)//sec Interrupt {rtc_get ();//Update Time}if (Rtc_getitstatus ( RTC_IT_ALR)!=reset)//Alarm clock Interrupt {rtc_clearitpendingbit (RTC_IT_ALR);//clear Alarm clock interrupt}rtc_clearitpendingbit (rtc_it_sec| RTC_IT_OW);//Clear Interrupt rtc_waitforlasttask ();}

We have a 1970-year benchmark, that is, when the counter starts from 0 on January 1, 1970, 00 seconds 00:00.

Say a more careless place (cause debugging for a night is not tuned), in writing Rtc_get () function (update time) accidentally put a 16-bit variable as 32 of the use of the. The result is a busy night all the buzz has not found what is wrong, in the morning until noon to fix. Sad

Rtc.h

#ifndef _rtc_h#define _rtc_h#include "sys.h" #include "delay.h" #include "usart.h" typedef struct{vu8 hour;  Vu8 min;  Vu8 sec;  Gregorian and lunar calendar year  vu16 w_year;  Vu8 w_month;vu8 w_date;vu8 Week;} _calendar_obj;extern _calendar_obj calendar;//Calendar Structural body//void disp_time (U8 x,u8 y,u8 size); Start Display time//void disp_week (U8 x,u8 y,u8 size,u8 Lang) in the established position;//Displays the week U8 rtc_init (void) in the specified position; Initialize RTC, return 0, fail; 1, success; U8 Is_leapyear (U16 year); Common year, Leap year judgment U8 rtc_get (void); Update Time U8 Rtc_get_week (U16 year,u8 month,u8 Day), U8 Rtc_set (U16 syear,u8 smon,u8 sday,u8 hour,u8 min,u8 sec);//Set Time #endif

Main function

#include "led.h" #include "delay.h" #include "sys.h" #include "usart.h" #include "lcd.h" #include "usmart.h" #include " Rtc.h "void init (void) {nvic_configuration ();d elay_init (); Uart_init (9600); Led_init ();  Lcd_init (); Usmart_dev.init (72);//Initialize Smart component}int main (void) {U8 t;init ();   Point_color=red;while (Rtc_init ())//RTC initialization, be sure to initialize the success {lcd_showstring (60,130,200,16,16, "RTC error! ");d Elay_ms (800); Lcd_showstring (60,130,200,16,16, "RTC Trying ...");   Display time point_color=blue;//set the font to Blue lcd_showstring (60,130,200,16,16, "--");     Lcd_showstring (60,162,200,16,16, "::"); while (1) {if (t!=calendar.sec) {t=calendar.sec;  Lcd_shownum (60,130,calendar.w_year,4,16);  Lcd_shownum (100,130,calendar.w_month,1,16); Lcd_shownum (124,130,calendar.w_date,2,16); Switch (calendar.week) {case 0:lcd_showstring (60,148,200,16,16, "Sunday"); Break;case 1:lcd_showstring ( 60,148,200,16,16, "Monday"), Break;case 2:lcd_showstring (60,148,200,16,16, "Tuesday"); Break;case 3:LCD_ShowString ( 60,148,200,16,16, "Wednesday");Case 4:lcd_showstring (60,148,200,16,16, "Thursday"), Break;case 5:lcd_showstring (60,148,200,16,16, "Friday");  Case 6:lcd_showstring (60,148,200,16,16, "Saturday");  }lcd_shownum (60,162,calendar.hour,2,16);  Lcd_shownum (84,162,calendar.min,2,16); Lcd_shownum (108,162,calendar.sec,2,16); led0=! LED0;}  Delay_ms (10); }  }


You can set any time by Usmart.

Cortex_m3_stm32 Embedded Learning Note (14): RTC Real-time clock (seconds interrupt)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.