STM32
直播中

laisvl

8年用户 1024经验值
私信 关注
[问答]

如何去实现一种RTC闹钟的LCD屏幕显示设计呢

如何去实现一种RTC闹钟的LCD屏幕显示设计呢?怎样去编写其代码呢?

回帖(1)

王聪

2021-12-1 13:34:22
基于正点原子的RTC
实验效果
LCD屏幕显示年月日时分秒设置任意时间到时间蜂鸣器启动直接
上代码
函数
简单说 就是初始化各个部件

然后让LED1 闪烁来提示系统的正常运行
显示屏显示实时时间
#include "led.h"
#include "delay.h"
#include "key.h"
#include "sys.h"
#include "lcd.h"
#include "usart.h"       
#include "usmart.h"         
#include "rtc.h"
#include "oled.h"
#include "beep.h"

int main(void)
{         
        u8 t=0;       
        delay_init();                               
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
        uart_init(115200);                 //
        LED_Init();                             //
        LCD_Init();
  OLED_Init();                        //
        OLED_Clear();         
        usmart_dev.init(SystemCoreClock/1000000);        //
  BEEP_Init();          
        RTC_Init();                                  //
        POINT_COLOR=RED;//
        LCD_ShowString(60,50,200,16,16,"Elite STM32");       
        LCD_ShowString(60,70,200,16,16,"RTC TEST");       
        LCD_ShowString(60,90,200,16,16,"ATOM@ALIENTEK");
        LCD_ShowString(60,110,200,16,16,"2015/1/14");               
        //ÏÔʾʱ¼ä
        POINT_COLOR=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);
      OLED_ShowNum(0,2,calendar.w_year,4,16);                       
                        //LCD_ShowNum(100,130,calendar.w_month,2,16);
      OLED_ShowNum(0,4,calendar.w_month,2,16);               
                        //LCD_ShowNum(124,130,calendar.w_date,2,16);
      OLED_ShowNum(0,6,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");
                                        break;
                                case 4:
                                        LCD_ShowString(60,148,200,16,16,"Thursday ");
                                        break;
                                case 5:
                                        LCD_ShowString(60,148,200,16,16,"Friday   ");
                                        break;
                                case 6:
                                        LCD_ShowString(60,148,200,16,16,"Saturday ");
                                        break;  
                        }
                        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);                                                                  
        };  
}
RTC配置函数
这里说明一下 我的代码是可以直接复制替换的
说下基于原子我修改了哪些
使能了时钟和闹钟中断 之前只使能了时钟(RTC_ITConfig(RTC_IT_SEC|RTC_IT_ALR, ENABLE);)
调用了设置闹钟值的函数(RTC_Alarm_Set(2021,1,13,16,39,59);)




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


          
_calendar_obj calendar;

static void RTC_NVIC_Config(void)
{       
  NVIC_InitTypeDef NVIC_InitStructure;
        NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn;               
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;       
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;       
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;               
        NVIC_Init(&NVIC_InitStructure);               
}




u8 RTC_Init(void)
{


    u8 temp=0;
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);       
        PWR_BackupAccessCmd(ENABLE);       
        if (BKP_ReadBackupRegister(BKP_DR1) != 0x5051)               
                {                                  
                BKP_DeInit();
                RCC_LSEConfig(RCC_LSE_ON);       
                while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET&&temp<250)       
                        {
                        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);       
                RTC_WaitForLastTask();       
                RTC_EnterConfigMode();
                RTC_SetPrescaler(32767);
                RTC_WaitForLastTask();       
                RTC_Set(2021,1,13,16,38,59);  
        RTC_Alarm_Set(2021,1,13,16,39,59);                       
                RTC_ExitConfigMode();
                BKP_WriteBackupRegister(BKP_DR1, 0X5051);       
                }
        else//ϵͳ¼ÌÐø¼Æʱ
                {


                RTC_WaitForSynchro();       
                RTC_ITConfig(RTC_IT_SEC, ENABLE);       
                RTC_WaitForLastTask();       
                }
        RTC_NVIC_Config();                                                 
        RTC_Get();       
        return 0;


}                                                     

void RTC_IRQHandler(void)
{                 
        if (RTC_GetITStatus(RTC_IT_SEC) != RESET)
        {                                                       
                RTC_Get();   
        }
        if(RTC_GetITStatus(RTC_IT_ALR)!= RESET)
        {
                RTC_ClearITPendingBit(RTC_IT_ALR);                         
          RTC_Get();                               
          printf("Alarm Time:%d-%d-%d %d:%d:%dn",calendar.w_year,calendar.w_month,calendar.w_date,calendar.hour,calendar.min,calendar.sec);
                BEEP=1;
          }                                                                                                    
        RTC_ClearITPendingBit(RTC_IT_SEC|RTC_IT_OW);               
        RTC_WaitForLastTask();                                                                                           
}


u8 Is_Leap_Year(u16 year)
{                          
        if(year%4==0) //
        {
                if(year%100==0)
                {
                        if(year%400==0)return 1;  
                        else return 0;   
                }else return 1;   
        }else return 0;       
}                                   
                                                                                 
u8 const table_week[12]={0,3,3,6,1,4,6,2,5,0,3,5};
const u8 mon_table[12]={31,28,31,30,31,30,31,31,30,31,30,31};
u8 RTC_Set(u16 syear,u8 smon,u8 sday,u8 hour,u8 min,u8 sec)
{
        u16 t;
        u32 seccount=0;
        if(syear<1970||syear>2099)return 1;          
        for(t=1970;t         {
                if(Is_Leap_Year(t))seccount+=31622400;
                else seccount+=31536000;                          
        }
        smon-=1;
        for(t=0;t         {
                seccount+=(u32)mon_table[t]*86400;
                if(Is_Leap_Year(syear)&&t==1)seccount+=86400;          
        }
        seccount+=(u32)(sday-1)*86400;
        seccount+=(u32)hour*3600;
    seccount+=(u32)min*60;       
        seccount+=sec;


        RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);       
        PWR_BackupAccessCmd(ENABLE);        //
        RTC_SetCounter(seccount);        //
        RTC_WaitForLastTask();        //       
        return 0;            
}




u8 RTC_Alarm_Set(u16 syear,u8 smon,u8 sday,u8 hour,u8 min,u8 sec)
{
        u16 t;
        u32 seccount=0;
        if(syear<1970||syear>2099)return 1;          
        for(t=1970;t         {
                if(Is_Leap_Year(t))seccount+=31622400;
                else seccount+=31536000;                         
        }
        smon-=1;
        for(t=0;t         {
                seccount+=(u32)mon_table[t]*86400;
                if(Is_Leap_Year(syear)&&t==1)seccount+=86400;          
        }
        seccount+=(u32)(sday-1)*86400;
        seccount+=(u32)hour*3600;
    seccount+=(u32)min*60;         
        seccount+=sec;                            
        //ÉèÖÃʱÖÓ
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);       
        PWR_BackupAccessCmd(ENABLE);         
        RTC_SetAlarm(seccount);
        RTC_WaitForLastTask();       
       
        return 0;            
}
u8 RTC_Get(void)
{
        static u16 daycnt=0;
        u32 timecount=0;
        u32 temp=0;
        u16 temp1=0;          
    timecount=RTC_GetCounter();         
        temp=timecount/86400;
        if(daycnt!=temp)
        {          
                daycnt=temp;
                temp1=1970;       
                while(temp>=365)
                {                                 
                        if(Is_Leap_Year(temp1))
                        {
                                if(temp>=366)temp-=366;
                                else {temp1++;break;}  
                        }
                        else temp-=365;          //ƽÄê
                        temp1++;  
                }   
                calendar.w_year=temp1;
                temp1=0;
                while(temp>=28)
                {
                        if(Is_Leap_Year(calendar.w_year)&&temp1==1)
                        {
                                if(temp>=29)temp-=29;
                                else break;
                        }
                        else
                        {
                                if(temp>=mon_table[temp1])temp-=mon_table[temp1];
                                else break;
                        }
                        temp1++;  
                }
                calendar.w_month=temp1+1;       
                calendar.w_date=temp+1;         
        }
        temp=timecount%86400;                               
        calendar.hour=temp/3600;            
        calendar.min=(temp%3600)/60;        
        calendar.sec=(temp%3600)%60;        
        calendar.week=RTC_Get_Week(calendar.w_year,calendar.w_month,calendar.w_date);  
        return 0;
}         
                                                                                                                                                                                 
u8 RTC_Get_Week(u16 year,u8 month,u8 day)
{       
        u16 temp2;
        u8 yearH,yearL;
       
        yearH=year/100;        yearL=year%100;  
        if (yearH>19)yearL+=100;
        temp2=yearL+yearL/4;
        temp2=temp2%7;
        temp2=temp2+day+table_week[month-1];
        if (yearL%4==0&&month<3)temp2--;
        return(temp2%7);
}                          
小贴士:
RTC 具有写保护功能每次操作都要修改掉
if (BKP_ReadBackupRegister(BKP_DR1) != 0x5051)
BKP_WriteBackupRegister(BKP_DR1, 0X5051);
所有行代码的值最就是5051和5050m
如果程序报错很可能是以下
没有添加蜂鸣器源文件和头文件
主函数没有初始化蜂鸣器
举报

更多回帖

发帖
×
20
完善资料,
赚取积分