mini板子RTC电子时钟如何让时间自动走动,是不是我的配置有问题了

2019-08-14 15:38发布

最近想用RTC实现一个类似电子表的功能,就是让显示在液晶上面的时间可以自动走动,并且能通过按键修改日期,不知道哪里出现问题了,改了半天也没有成功,已实现部分通过按键来修改时间的功能,把内部RTC得到时间赋值给我新建的结构体time里面时,按键功能就实现不了,而且这个时间不知道为什么走不了,还有就是他一按复位键,时间的秒就会加一,这是为什么?这下面是RTC的配置与秒中断函数;和主函数。u8 RTC_Init(void)
{
        //检查是不是第一次配置时钟
        u8 temp=0;
       
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);        //使能PWR和BKP外设时钟   
       
        PWR_BackupAccessCmd(ENABLE);                            //使能后备寄存器访问; 默认情况下是禁止访问后备区域,避免误操作
       
        if (BKP_ReadBackupRegister(BKP_DR1) != 0x5050)                //从指定的后备寄存器中读出数据:读出了与写入的指定数据不相乎
        {                                
                BKP_DeInit();                      //复位备份区域        
                RCC_LSEConfig(RCC_LSE_ON);        //设置外部低速晶振(LSE),使用外设低速晶振  
                while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)        //检查指定的RCC标志位设置与否,等待低速晶振就绪  
                {
                        temp++;
                        delay_ms(10);//使能外部低速振荡器,一般要先判断 RCC_BDCR 的 LSERDY位来确定低速振荡器已经就绪了
                }//如果2.5s还没有准备就绪,则说明时钟初始化失败
                if(temp>=250)
                        return 1;                 //初始化时钟失败,晶振有问题            
               
                //如果时钟初始化是没有问题的则执行以下代码
                RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);//设置RTC时钟(RTCCLK),选择LSE作为RTC时钟   
                RCC_RTCCLKCmd(ENABLE);                        //使能RTC时钟  
                //以上执行完之后则表示时钟已准备就绪
               
                RTC_WaitForLastTask();                       //等待最近一次对RTC寄存器的写操作完成
                RTC_WaitForSynchro();                               //等待RTC寄存器同步  
                RTC_ITConfig(RTC_IT_SEC, ENABLE);                   //使能RTC秒中断
                RTC_WaitForLastTask();                       //等待最近一次对RTC寄存器的写操作完成
               
                RTC_EnterConfigMode();                 //允许配置       
                RTC_SetPrescaler(32767);               //设置RTC预分频的值 32.768KHZ/(32767+1)=1HZ 也就是1s一个周期, 在这个RTC_SetPrescaler()函数里面其实已经有设置进入配置模式和退出配置模式 此时再次写是为了以防万一
                RTC_WaitForLastTask();                       //等待最近一次对RTC寄存器的写操作完成
               
                RTC_Set(2017,5,29,20,35,55);           //设置时间        当前时间  配置RTC_CNT寄存器
               
                RTC_ExitConfigMode();                  //退出配置模式  
                BKP_WriteBackupRegister(BKP_DR1, 0X5050);//向指定的后备寄存器中写入用户程序数据
        }
  else//系统继续计时
  {
                RTC_WaitForSynchro();                   //等待最近一次对RTC寄存器的写操作完成
                RTC_ITConfig(RTC_IT_SEC, ENABLE);        //使能RTC秒中断   使用过RTC寄存器
                RTC_WaitForLastTask();                  //等待最近一次对RTC寄存器的写操作完成
  }
        RTC_NVIC_Config();//RCT中断分组设置                                                         
        RTC_Get();        //更新时间       
        return 0;         //ok

}                                                     
//RTC时钟中断
//每秒触发一次  
//extern u16 tcnt;
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_ClearITPendingBit(RTC_IT_SEC|RTC_IT_OW);//清闹钟中断
        RTC_WaitForLastTask();                                                                                           
}

#include "led.h"
#include "delay.h"
#include "sys.h"
#include "usart.h"
#include "lcd.h"
#include "usmart.h"
#include "rtc.h"
#include "key.h"

_calendar_obj time;
int main(void)
{
        u8 t;       
  u8 key;
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);// 设置中断优先级分组2
        delay_init();                                               //延时函数初始化          
        uart_init(9600);                                            //串口初始化为9600
        LED_Init();                                                             //初始化与LED连接的硬件接口
        LCD_Init();                                                             //初始化LCD
        KEY_Init();
        usmart_dev.init(72);                                 //初始化USMART                                        
        POINT_COLOR=RED;                               //设置字体为红 {MOD}
        LCD_ShowString(60,50,200,16,16,"Mini 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,"2014/3/8");       
        while(RTC_Init())                                           //RTC初始化        ,一定要初始化成功
        {
                LCD_ShowString(60,130,200,16,16,"RTC ERROR!   ");       
                delay_ms(800);
                LCD_ShowString(60,130,200,16,16,"RTC Trying...");       
        }                                                                   
        //显示时间
        POINT_COLOR=BLUE;//设置字体为蓝 {MOD}                                         
        LCD_ShowString(60,130,200,16,16,"    -  -     ");          
        LCD_ShowString(60,170,200,16,16,"  :  :  ");                
  time.w_year = 2013;
  time.w_month = 12;
  time.w_date = 24;
  time.week = 2;
  time.hour = 12;
  time.min = 0;
  time.sec = 0;   
        while(1)
        {       
          time=calendar;
                RTC_Set(time.w_year,time.w_month,time.w_date,time.hour,time.min,time.sec);
                if(t!=calendar.sec)
                {
                        t=calendar.sec;
                        LCD_ShowNum(60,130,time.w_year,4,16);                                                                          
                        LCD_ShowNum(100,130,time.w_month,2,16);                                                                          
                        LCD_ShowNum(124,130,time.w_date,2,16);         
                        switch(calendar.week)
                        {
                                case 0:
                                        LCD_ShowString(60,150,200,16,16,"Sunday   ");
                                        break;
                                case 1:
                                        LCD_ShowString(60,150,200,16,16,"Monday   ");
                                        break;
                                case 2:
                                        LCD_ShowString(60,150,200,16,16,"Tuesday  ");
                                        break;
                                case 3:
                                        LCD_ShowString(60,150,200,16,16,"Wednesday");
                                        break;
                                case 4:
                                        LCD_ShowString(60,150,200,16,16,"Thursday ");
                                        break;
                                case 5:
                                        LCD_ShowString(60,150,200,16,16,"Friday   ");
                                        break;
                                case 6:
                                        LCD_ShowString(60,150,200,16,16,"Saturday ");
                                        break;  
                        }
                        LCD_ShowNum(60,170,time.hour,2,16);                                                                          
                        LCD_ShowNum(84,170,time.min,2,16);                                                                          
                        LCD_ShowNum(108,170,time.sec,2,16);       
                delay_ms(10);
                }

       
        key=KEY_Scan(0);                       
        switch(key)
                {                                 
                        case 1:
                        if(time.sec==0) time.sec=59;
                  else time.sec--;
                  RTC_Set(time.w_year,time.w_month,time.w_date,time.hour,time.min,time.sec);
                        LCD_ShowNum(108,170,time.sec,2,16);
                                break;
                        case 2:
                        if(time.min==0) time.min=59;
                  else time.min--;
                  RTC_Set(time.w_year,time.w_month,time.w_date,time.hour,time.min,time.sec);
                        LCD_ShowNum(84,170,time.min,2,16);
                                break;
                        case 3:
      if(time.hour==0) time.hour=23;
                  else time.hour--;
                  RTC_Set(time.w_year,time.w_month,time.w_date,time.hour,time.min,time.sec);               
                  LCD_ShowNum(60,170,time.hour,2,16);                               
                          break;       
                        default:delay_ms(10);       
        }
        }
}       



友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。