最近想用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;                               //设置字体为红色  
        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;//设置字体为蓝色                                          
        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);         
        } 
        } 
}         
 
 
 
 |