你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

基于STM32 RTC闹钟时钟配置经验分享

[复制链接]
攻城狮Melo 发布时间:2023-5-1 18:25
实验效果
LCD屏幕显示 年月日时分秒 设置任意时间 到时间蜂鸣器启动

主函数
  1. 简单说 就是初始化各个部件
  2. 然后让LED1 闪烁来提示系统的正常运行
  3. 显示屏显示实时时间
  4. #include "led.h"
  5. #include "delay.h"
  6. #include "key.h"
  7. #include "sys.h"
  8. #include "lcd.h"
  9. #include "usart.h"        
  10. #include "usmart.h"         
  11. #include "rtc.h"
  12. #include "oled.h"
  13. #include "beep.h"

  14. int main(void)
  15. {         
  16.          u8 t=0;        
  17.         delay_init();                              
  18.         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
  19.         uart_init(115200);                 //
  20.          LED_Init();                             //
  21.         LCD_Init();
  22.   OLED_Init();                        //
  23.         OLED_Clear();         
  24.         usmart_dev.init(SystemCoreClock/1000000);        //
  25.   BEEP_Init();         
  26.         RTC_Init();                                  //
  27.         POINT_COLOR=RED;//
  28.         LCD_ShowString(60,50,200,16,16,"Elite STM32");        
  29.         LCD_ShowString(60,70,200,16,16,"RTC TEST");        
  30.         LCD_ShowString(60,90,200,16,16,"ATOM@ALIENTEK");
  31.         LCD_ShowString(60,110,200,16,16,"2015/1/14");               
  32.         //ÏÔʾʱ¼ä
  33.         POINT_COLOR=BLUE;//
  34.         LCD_ShowString(60,130,200,16,16,"    -  -  ");           
  35.         LCD_ShowString(60,162,200,16,16,"  :  :  ");                    
  36.         while(1)
  37.         {                                                                    
  38.                 if(t!=calendar.sec)
  39.                 {
  40.                         t=calendar.sec;
  41.                         //LCD_ShowNum(60,130,calendar.w_year,4,16);
  42.       OLED_ShowNum(0,2,calendar.w_year,4,16);                        
  43.                         //LCD_ShowNum(100,130,calendar.w_month,2,16);
  44.       OLED_ShowNum(0,4,calendar.w_month,2,16);               
  45.                         //LCD_ShowNum(124,130,calendar.w_date,2,16);
  46.       OLED_ShowNum(0,6,calendar.w_date,2,16);                        
  47.                         switch(calendar.week)
  48.                         {
  49.                                 case 0:
  50.                                         LCD_ShowString(60,148,200,16,16,"Sunday   ");
  51.                                         break;
  52.                                 case 1:
  53.                                         LCD_ShowString(60,148,200,16,16,"Monday   ");
  54.                                         break;
  55.                                 case 2:
  56.                                         LCD_ShowString(60,148,200,16,16,"Tuesday  ");
  57.                                         break;
  58.                                 case 3:
  59.                                         LCD_ShowString(60,148,200,16,16,"Wednesday");
  60.                                         break;
  61.                                 case 4:
  62.                                         LCD_ShowString(60,148,200,16,16,"Thursday ");
  63.                                         break;
  64.                                 case 5:
  65.                                         LCD_ShowString(60,148,200,16,16,"Friday   ");
  66.                                         break;
  67.                                 case 6:
  68.                                         LCD_ShowString(60,148,200,16,16,"Saturday ");
  69.                                         break;  
  70.                         }
  71.                         LCD_ShowNum(60,162,calendar.hour,2,16);                                                                          
  72.                         LCD_ShowNum(84,162,calendar.min,2,16);                                                                          
  73.                         LCD_ShowNum(108,162,calendar.sec,2,16);
  74.                         LED0=!LED0;
  75.                 }        
  76.                 delay_ms(10);                                                                  
  77.         };  
  78. }
复制代码

RTC配置函数
这里说明一下 我的代码是可以直接复制替换的
说下基于原子我修改了哪些
使能了时钟和闹钟中断 之前只使能了时钟(RTC_ITConfig(RTC_IT_SEC|RTC_IT_ALR, ENABLE);)
调用了设置闹钟值的函数(RTC_Alarm_Set(2021,1,13,16,39,59);)

  1. 在闹钟中断的函数中 增加了蜂鸣器 启动 BEEP=1;
  2. #include "sys.h"
  3. #include "delay.h"
  4. #include "usart.h"
  5. #include "rtc.h"         
  6. #include "led.h"
  7. #include "beep.h"

  8.            
  9. _calendar_obj calendar;

  10. static void RTC_NVIC_Config(void)
  11. {        
  12.   NVIC_InitTypeDef NVIC_InitStructure;
  13.         NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn;               
  14.         NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;        
  15.         NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;        
  16.         NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;               
  17.         NVIC_Init(&NVIC_InitStructure);               
  18. }


  19. u8 RTC_Init(void)
  20. {

  21.     u8 temp=0;
  22.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);        
  23.         PWR_BackupAccessCmd(ENABLE);        
  24.         if (BKP_ReadBackupRegister(BKP_DR1) != 0x5051)               
  25.                 {                                 
  26.                 BKP_DeInit();
  27.                 RCC_LSEConfig(RCC_LSE_ON);        
  28.                 while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET&&temp<250)        
  29.                         {
  30.                         temp++;
  31.                         delay_ms(10);
  32.                         }
  33.                 if(temp>=250)return 1;            
  34.                 RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);                  
  35.                 RCC_RTCCLKCmd(ENABLE);        
  36.                 RTC_WaitForLastTask();        
  37.                 RTC_WaitForSynchro();                 
  38.                 RTC_ITConfig(RTC_IT_SEC|RTC_IT_ALR, ENABLE);        
  39.                 RTC_WaitForLastTask();        
  40.                 RTC_EnterConfigMode();
  41.                 RTC_SetPrescaler(32767);
  42.                 RTC_WaitForLastTask();        
  43.                 RTC_Set(2021,1,13,16,38,59);  
  44.         RTC_Alarm_Set(2021,1,13,16,39,59);                        
  45.                 RTC_ExitConfigMode();
  46.                 BKP_WriteBackupRegister(BKP_DR1, 0X5051);        
  47.                 }
  48.         else//ϵͳ¼ÌÐø¼ÆÊ±
  49.                 {

  50.                 RTC_WaitForSynchro();        
  51.                 RTC_ITConfig(RTC_IT_SEC, ENABLE);        
  52.                 RTC_WaitForLastTask();        
  53.                 }
  54.         RTC_NVIC_Config();                                                
  55.         RTC_Get();        
  56.         return 0;

  57. }                                                     

  58. void RTC_IRQHandler(void)
  59. {                 
  60.         if (RTC_GetITStatus(RTC_IT_SEC) != RESET)
  61.         {                                                        
  62.                 RTC_Get();   
  63.          }
  64.         if(RTC_GetITStatus(RTC_IT_ALR)!= RESET)
  65.         {
  66.                 RTC_ClearITPendingBit(RTC_IT_ALR);                          
  67.           RTC_Get();                                
  68.           printf("Alarm Time:%d-%d-%d %d:%d:%d\n",calendar.w_year,calendar.w_month,calendar.w_date,calendar.hour,calendar.min,calendar.sec);
  69.                 BEEP=1;
  70.           }                                                                                                   
  71.         RTC_ClearITPendingBit(RTC_IT_SEC|RTC_IT_OW);               
  72.         RTC_WaitForLastTask();                                                                                          
  73. }

  74. u8 Is_Leap_Year(u16 year)
  75. {                          
  76.         if(year%4==0) //
  77.         {
  78.                 if(year%100==0)
  79.                 {
  80.                         if(year%400==0)return 1;  
  81.                         else return 0;   
  82.                 }else return 1;   
  83.         }else return 0;        
  84. }                                    
  85.                                                                                  
  86. u8 const table_week[12]={0,3,3,6,1,4,6,2,5,0,3,5};
  87. const u8 mon_table[12]={31,28,31,30,31,30,31,31,30,31,30,31};
  88. u8 RTC_Set(u16 syear,u8 smon,u8 sday,u8 hour,u8 min,u8 sec)
  89. {
  90.         u16 t;
  91.         u32 seccount=0;
  92.         if(syear<1970||syear>2099)return 1;           
  93.         for(t=1970;t<syear;t++)        
  94.         {
  95.                 if(Is_Leap_Year(t))seccount+=31622400;
  96.                 else seccount+=31536000;                          
  97.         }
  98.         smon-=1;
  99.         for(t=0;t<smon;t++)           
  100.         {
  101.                 seccount+=(u32)mon_table[t]*86400;
  102.                 if(Is_Leap_Year(syear)&&t==1)seccount+=86400;           
  103.         }
  104.         seccount+=(u32)(sday-1)*86400;
  105.         seccount+=(u32)hour*3600;
  106.     seccount+=(u32)min*60;        
  107.         seccount+=sec;

  108.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);        
  109.         PWR_BackupAccessCmd(ENABLE);        //
  110.         RTC_SetCounter(seccount);        //
  111.         RTC_WaitForLastTask();        //        
  112.         return 0;            
  113. }


  114. u8 RTC_Alarm_Set(u16 syear,u8 smon,u8 sday,u8 hour,u8 min,u8 sec)
  115. {
  116.         u16 t;
  117.         u32 seccount=0;
  118.         if(syear<1970||syear>2099)return 1;           
  119.         for(t=1970;t<syear;t++)        
  120.         {
  121.                 if(Is_Leap_Year(t))seccount+=31622400;
  122.                 else seccount+=31536000;                        
  123.         }
  124.         smon-=1;
  125.         for(t=0;t<smon;t++)           
  126.         {
  127.                 seccount+=(u32)mon_table[t]*86400;
  128.                 if(Is_Leap_Year(syear)&&t==1)seccount+=86400;           
  129.         }
  130.         seccount+=(u32)(sday-1)*86400;
  131.         seccount+=(u32)hour*3600;
  132.     seccount+=(u32)min*60;         
  133.         seccount+=sec;                           
  134.         //ÉèÖÃʱÖÓ
  135.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);        
  136.         PWR_BackupAccessCmd(ENABLE);         
  137.         RTC_SetAlarm(seccount);
  138.         RTC_WaitForLastTask();        
  139.         
  140.         return 0;            
  141. }
  142. u8 RTC_Get(void)
  143. {
  144.         static u16 daycnt=0;
  145.         u32 timecount=0;
  146.         u32 temp=0;
  147.         u16 temp1=0;         
  148.     timecount=RTC_GetCounter();         
  149.          temp=timecount/86400;
  150.         if(daycnt!=temp)
  151.         {         
  152.                 daycnt=temp;
  153.                 temp1=1970;        
  154.                 while(temp>=365)
  155.                 {                                 
  156.                         if(Is_Leap_Year(temp1))
  157.                         {
  158.                                 if(temp>=366)temp-=366;
  159.                                 else {temp1++;break;}  
  160.                         }
  161.                         else temp-=365;          //ƽÄê
  162.                         temp1++;  
  163.                 }   
  164.                 calendar.w_year=temp1;
  165.                 temp1=0;
  166.                 while(temp>=28)
  167.                 {
  168.                         if(Is_Leap_Year(calendar.w_year)&&temp1==1)
  169.                         {
  170.                                 if(temp>=29)temp-=29;
  171.                                 else break;
  172.                         }
  173.                         else
  174.                         {
  175.                                 if(temp>=mon_table[temp1])temp-=mon_table[temp1];
  176.                                 else break;
  177.                         }
  178.                         temp1++;  
  179.                 }
  180.                 calendar.w_month=temp1+1;        
  181.                 calendar.w_date=temp+1;         
  182.         }
  183.         temp=timecount%86400;                                
  184.         calendar.hour=temp/3600;            
  185.         calendar.min=(temp%3600)/60;         
  186.         calendar.sec=(temp%3600)%60;         
  187.         calendar.week=RTC_Get_Week(calendar.w_year,calendar.w_month,calendar.w_date);  
  188.         return 0;
  189. }         
  190.                                                                                                                                                                                  
  191. u8 RTC_Get_Week(u16 year,u8 month,u8 day)
  192. {        
  193.         u16 temp2;
  194.         u8 yearH,yearL;
  195.         
  196.         yearH=year/100;        yearL=year%100;  
  197.         if (yearH>19)yearL+=100;
  198.         temp2=yearL+yearL/4;
  199.         temp2=temp2%7;
  200.         temp2=temp2+day+table_week[month-1];
  201.         if (yearL%4==0&&month<3)temp2--;
  202.         return(temp2%7);
  203. }                          


复制代码

小贴士:
RTC具有写保护功能 每次操作要修改掉
if (BKP_ReadBackupRegister(BKP_DR1) != 0x5051)
BKP_WriteBackupRegister(BKP_DR1, 0X5051);
这两行代码的值 最简便就是5051和5050变换
如果程序报错 很可能是以下问题
没有添加蜂鸣器源文件和头文件
main函数没有初始化蜂鸣器
————————————————
版权声明:文某9

如有侵权请联系删除


收藏 评论0 发布时间:2023-5-1 18:25

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版