if(BKP->DR1!=0X5050)//第一次配置
{
RCC->APB1ENR|=1<<28; //使能电源时钟
RCC->APB1ENR|=1<<27; //使能备份时钟
PWR->CR|=1<<8; //取消备份区写保护
RCC->BDCR|=1<<16; //备份区域软复位
RCC->BDCR&=~(1<<16); //备份区域软复位结束
RCC->BDCR|=1<<0; //开启外部低速振荡器
while((!(RCC->BDCR&0X02))&&temp<250)//等待外部时钟就绪
{
temp++;
delay_ms(10);
};
if(temp>=250)return 1;//初始化时钟失败,晶振有问题
RCC->BDCR|=1<<8; //LSI作为RTC时钟
RCC->BDCR|=1<<15;//RTC时钟使能
while(!(RTC->CRL&(1<<5)));//等待RTC寄存器操作完成
while(!(RTC->CRL&(1<<3)));//等待RTC寄存器同步
RTC->CRH|=0X03; //允许秒中断
while(!(RTC->CRL&(1<<5)));//等待RTC寄存器操作完成
RTC->CRL|=1<<4; //允许配置
RTC->  RLH=0X0000;
RTC->  RLL=32767; //时钟周期设置(有待观察,看是否跑慢了?)理论值:32767
// Auto_Time_Set();
RTC_Set(2009,12,2,10,0,55); //设置时间
Rtc_ALARM_Set(2013,5,7,19,41,0);
RTC->CRL&=~(1<<4); //配置更新
while(!(RTC->CRL&(1<<5))); //等待RTC寄存器操作完成
BKP->DR1=0X5050;
//BKP_Write(1,0X5050);;//在寄存器1标记已经开启了
//printf("FIRST TIME\n");
}else//系统继续计时
{
while(!(RTC->CRL&(1<<3)));//等待RTC寄存器同步
RTC->CRH|=0X03; //允许秒中断
while(!(RTC->CRL&(1<<5)));//等待RTC寄存器操作完成
//printf("OK\n");
}
MY_NVIC_Init(0,0,RTC_IRQChannel,2);//RTC,G2,P2,S2.优先级最低
RTC_Get();//更新时间
//Rtc_ALARM_Set(2013,5,7,11,47,30);
return 0; //ok
闹钟设置函数如下:
//将时间转化为到1970年1月1日的总秒数
//Bugs:此函数秒数会多20左右,所以函数返回值做了校正,校正后没有问题
//待优化
u32 Date_TO_Sec(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<syear;t++) //把所有年份的秒钟相加
{
if(Is_Leap_Year(t))seccount+=31622400;//闰年的秒钟数
else seccount+=31536000; //平年的秒钟数
}
smon-=1;
for(t=0;t<smon;t++) //把前面月份的秒钟数相加
{
seccount+=(u32)mon_table[t]*86400;//月份秒钟数相加
if(Is_Leap_Year(syear)&&t==1)seccount+=86400;//闰年2月份增加一天的秒钟数
}
seccount+=(u32)(sday-1)*86400;//把前面日期的秒钟数相加
seccount+=(u32)hour*3600;//小时秒钟数
seccount+=(u32)min*60; //分钟秒钟数
seccount+=sec;//最后的秒钟加上去
return seccount; //校正20秒,原因不详
}
void Rtc_ALARM_Set(u16 year,u8 mon,u8 day,u8 hour,u8 min,u8 sec)
{
u32 s;
s=Date_TO_Sec(year,mon,day,hour,min,sec);
RTC->CRL|=1<<4; //允许配置
//while(!(RTC->CRL&(1<<5))); //RTOFF为1 才可以写入ALRL和ALRH寄存器
RTC->ALRL=s&0xffff; //取低16位
RTC->ALRH=s>>16; //取高16位
RTC->CRL&=~(1<<4); //开始RTC寄存器更新
while(!(RTC->CRL&(1<<5))); //等待RTC寄存器操作完成
}
为什么这样闹钟无效?求大神解释,谢谢!
|