OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 11445|回复: 10

RTC闹钟设置

[复制链接]

51

主题

123

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
347
金钱
347
注册时间
2012-5-20
在线时间
0 小时
发表于 2012-7-10 17:03:26 | 显示全部楼层 |阅读模式

  u8 RTC_Init(void)
{
 //检查是不是第一次配置时钟
  u8 temp=0;
   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
   RTC->ALRH=0X01E1; 
   RTC->ALRL=0X4000;                 
   Auto_Time_Set();
   RTC_Set(1971,1,1,0,53,10);  //设置时间  
   RTC->CRL&=~(1<<4);           //配置更新
   while(!(RTC->CRL&(1<<5)));   //等待RTC寄存器操作完成
   BKP->DR1=0x5050;            
  }
  else
  {
   while(!(RTC->CRL&(1<<3)));
   RTC->CRH|=0X03;
   while(!(RTC->CRL&(1<<5)));
   RTC->CRL|=1<<4;              //允许配置     
   RTC->ALRH=0X01E1; 
   RTC->ALRL=0X4200;                 
   RTC->CRL&=~(1<<4); 
   while(!(RTC->CRL&(1<<5)));
   
  }  
 MY_NVIC_Init(0,0,RTC_IRQChannel,2);//RTC,G2,P2,S2.优先级最低    
 RTC_Get();//更新时间
 return 0; //ok
}
红色为修改部分
在进行闹钟设置时,在if语句中的设置就可以让闹钟生效,进入中断执行闹钟下的语句
但是在else中设置 LCD就白屏了 什么都不显示  我想知道什么原因呢 我看了手册的RTC寄存器配置方法,看了好几次 感觉没错啊 ,求师兄帮忙,貌似是在WHILE语句中死循环了,我改为 else
  {
   while(!(RTC->CRL&(1<<3)));
   RTC->CRH|=0X03;
   while(!(RTC->CRL&(1<<5)));
   RTC->CRL|=1<<4;              //允许配置     
   RTC->ALRH=0X01E1; 
   RTC->ALRL=0X4200;                 
   RTC->CRL&=~(1<<4);  
      
  }  
去掉了最后的while(!(RTC->CRL&(1<<5)));,LCD显示了,但是秒钟不动了,屏幕定格了。
想知道哪里错了。如何改正?


正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

36

主题

96

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
244
金钱
244
注册时间
2012-11-11
在线时间
14 小时
发表于 2013-2-22 10:54:41 | 显示全部楼层
回复【楼主位】beisiqiu:
---------------------------------
请问后来你怎么解决的
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165536
金钱
165536
注册时间
2010-12-1
在线时间
2117 小时
发表于 2013-2-22 16:05:20 | 显示全部楼层
void calendar_alarm_init(_alarm_obj *alarmx) 
{   
   u32 curtime=0;
u32 temptime=0;
u32 destime=0XFFFFFFFF;//目标闹铃时间(s)设定到最大
  if(alarmx->weekmask)//必须要有闹钟存在,周日到周六任意一天 
{        
curtime=RTC->CNTH;//得到计数器中的值(秒钟数)
curtime<<=16;
curtime+=RTC->CNTL;    
//取一个与当前时间最接近的值作为闹钟寄存器的内容
temptime=curtime/86400; //得到当前运行天数(此处没有用到天数,仅作说明用)
temptime=temptime*86400;
  temptime+=(u32)alarmx->hour*3600+(u32)alarmx->min*60;//得到秒钟数
  if(temptime<=curtime)temptime+=86400;//执行时间已过,推迟到明天
  destime=temptime;//更改闹钟寄存器
  }
RCC->APB1ENR|=1<<28;//使能电源时钟
    RCC->APB1ENR|=1<<27;//使能备份时钟
PWR->CR|=1<<8;    //取消备份区写保护
//上面三步是必须的!
RTC->CRL|=1<<4;   //允许配置 
RTC->ALRL=destime&0xffff;
RTC->ALRH=destime>>16;
RTC->CRL&=~(1<<4);//配置更新
while(!(RTC->CRL&(1<<5)));//等待RTC寄存器操作完成  
}
请仔细看看,那个以上三步是必须的注释!!!
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

51

主题

154

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
409
金钱
409
注册时间
2012-10-24
在线时间
19 小时
发表于 2013-4-14 22:47:09 | 显示全部楼层
回复【3楼】正点原子:
---------------------------------
原子大哥!!!请问这是RTC闹钟的设置程序吗?其实我不怎么看得不明白,例如我要设置15:30的闹钟时间,请问如何设置?有个例子容易明白很多!谢谢
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165536
金钱
165536
注册时间
2010-12-1
在线时间
2117 小时
发表于 2013-4-14 23:04:09 | 显示全部楼层
综合例程就有闹钟设置部分,核心代码:
//重新初始化闹钟     
//alarmx:闹钟结构体
void calendar_alarm_init(_alarm_obj *alarmx) 
{   
   u32 curtime=0;
u32 temptime=0;
u32 destime=0XFFFFFFFF;//目标闹铃时间(s)设定到最大
  if(alarmx->weekmask)//必须要有闹钟存在,周日到周六任意一天 
{        
curtime=RTC->CNTH;//得到计数器中的值(秒钟数)
curtime<<=16;
curtime+=RTC->CNTL;    
//取一个与当前时间最接近的值作为闹钟寄存器的内容
temptime=curtime/86400; //得到当前运行天数(此处没有用到天数,仅作说明用)
temptime=temptime*86400;
  temptime+=(u32)alarmx->hour*3600+(u32)alarmx->min*60;//得到秒钟数
  if(temptime<=curtime)temptime+=86400;//执行时间已过,推迟到明天
  destime=temptime;//更改闹钟寄存器
  }
RCC->APB1ENR|=1<<28;//使能电源时钟
    RCC->APB1ENR|=1<<27;//使能备份时钟
PWR->CR|=1<<8;    //取消备份区写保护
//上面三步是必须的!
RTC->CRL|=1<<4;   //允许配置 
RTC->ALRL=destime&0xffff;
RTC->ALRH=destime>>16;
RTC->CRL&=~(1<<4);//配置更新
while(!(RTC->CRL&(1<<5)));//等待RTC寄存器操作完成  
}

其中_alarm_obj的结构体定义如下:
//闹钟结构体    
__packed typedef struct  
{       
u8  weekmask; //闹钟响铃掩码   
u8  ringsta; //闹铃状态及铃声标志.
//[7]:0,无闹铃;1,闹铃中;
//[6:3]:保留
//[2:0]:闹钟铃声类型
u8  hour;     //闹铃小时
u8  min; //闹铃分钟

u8 saveflag; //保存标志,0X0A,保存过了;其他,还从未保存    
}_alarm_obj;
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

51

主题

154

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
409
金钱
409
注册时间
2012-10-24
在线时间
19 小时
发表于 2013-4-15 20:20:00 | 显示全部楼层
回复【5楼】正点原子:
---------------------------------
谢谢!
回复 支持 反对

使用道具 举报

1

主题

40

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
449
金钱
449
注册时间
2013-5-22
在线时间
80 小时
发表于 2013-9-6 16:04:33 | 显示全部楼层
原子哥,能不能帮我看下,为什么这样配置闹钟中断一直都不行呢?
u8 RTC_Init(void)
{
//检查是不是第一次配置时钟
u8 temp=0;
u32 curtime=0;      //获取当前的秒钟数

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|=0X01;     //允许秒中断
/****************添加**************************/
RTC->CRH|=0X02;     //允许闹钟中断
// EXTI->IMR|=1<<17; 
// EXTI->RTSR|=1<<17;
/******************************************/

     while(!(RTC->CRL&(1<<5)));//等待RTC寄存器操作完成  
RTC->CRL|=1<<4;              //允许配置  
 
RTC->RLH=0X0000;
RTC->RLL=32767;          //时钟周期设置(有待观察,看是否跑慢了?)理论值:32767  
    
RTC_Set(2012,9,7,13,16,55);  //设置时间
/*************添加*******************************/
curtime=RTC->CNTH;//得到计数器中的值(秒钟数)
curtime<<=16;
curtime+=RTC->CNTL;    

RTC->ALRL=curtime&0xffff;
RTC->ALRH=curtime>>16 + 30;           //测试30秒后闹铃测试
/********************************************/  
RTC->CRL&=~(1<<4);           //配置更新
while(!(RTC->CRL&(1<<5)));   //等待RTC寄存器操作完成     
BKP->DR1=0X5050;  
  printf("FIRST TIME\n");
}
else//系统继续计时
{
     while(!(RTC->CRL&(1<<3)));//等待RTC寄存器同步  
     RTC->CRH|=0X01;     //允许秒中断
RTC->CRH|=0X02;     //允许闹钟中断
// EXTI->IMR|=1<<17; 
// EXTI->RTSR|=1<<17;
     while(!(RTC->CRL&(1<<5)));//等待RTC寄存器操作完成
printf("OK\n");
}        
MY_NVIC_Init(0,0,RTC_IRQChannel,2);//优先级设置    
RTC_Get();//更新时间 
return 0; //ok
}

void RTC_IRQHandler(void)
{
u32 curtime=0;      //获取当前的秒钟数  
if(RTC->CRL&0x0001)//秒钟中断
{
RTC_Get();//更新时间   
//printf("sec:%d\r\n",calendar.sec);
  }
if(RTC->CRL&0x0002)//闹钟中断
{
curtime=RTC->CNTH;//得到计数器中的值(秒钟数)
curtime<<=16;
curtime+=RTC->CNTL;   
RTC->CRL&=~(0x0002); //清闹钟中断   
   //printf("Alarm!\n");
LED1=!LED1;    

RTC->CRL|=1<<4;   //允许配置 
RTC->ALRL=curtime&0xffff;
RTC->ALRH=curtime>>16 + 30;
RTC->CRL&=~(1<<4);//配置更新
   }      
    RTC->CRL&=0X0FFA;         //清除溢出,秒钟中断标志
while(!(RTC->CRL&(1<<5)));//等待RTC寄存器操作完成                
}
回复 支持 反对

使用道具 举报

170

主题

917

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1824
金钱
1824
注册时间
2013-4-13
在线时间
63 小时
发表于 2014-6-11 22:17:28 | 显示全部楼层
试过了没有?
手艺人要内外兼修。
回复 支持 反对

使用道具 举报

7

主题

32

帖子

0

精华

新手上路

积分
40
金钱
40
注册时间
2015-4-16
在线时间
13 小时
发表于 2015-11-2 11:04:26 | 显示全部楼层
回复【5楼】正点原子:
---------------------------------
原子哥,能帮忙给个链接吗,stm32rtc定时闹钟的寄存器版啊,怎么找不到内??  谢谢
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165536
金钱
165536
注册时间
2010-12-1
在线时间
2117 小时
发表于 2015-11-2 21:51:43 | 显示全部楼层
回复【10楼】laoqier:
---------------------------------
下载最新例程吧,都有.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

0

主题

1

帖子

0

精华

新手入门

积分
16
金钱
16
注册时间
2016-7-11
在线时间
1 小时
发表于 2016-7-11 10:15:21 | 显示全部楼层
我这里闹钟数据ALRH和ALRL写不进去,始终是零。是什么原因呢?有人不能帮我解释一下吗。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-10 15:27

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表