为什么stm32里面stm32的rtc实现日历

stm32&rtc&几个要点
1.把响应的时钟打开
2.如果你需要rtc的闹钟功能,必须使能外部中断线17
3.配置NVIC_Configuration
,一个是RTC_IRQn,一个是RTCAlarm_IRQn;但是事实上,在stm32103VE上即使允许了RTCAlarm_IRQn这个中断请求,它也是不进入中断服务程序的;而是进入了全局中断服务程序RTC_IRQHandler();
注意:复位以后,虽说电源没有拔下,这样的话,BKP中的寄存器的值还在,但是此时是不能操作RTC寄存器的
还是需要重新使能电源和后备接口时钟、设置寄存器PWR_CR的DBP位使能对后备寄存器和RTC的访问
& RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR |
RCC_APB1Periph_BKP, ENABLE);
& PWR_BackupAccessCmd(ENABLE);
5.如果设置了闹钟的值,又使能了闹钟中断,又把外部中断线17使能了,这时就可以进入闹钟中断的服务程序了。
注意在服务程序中:
1.清除外部中断线17的中断悬挂位
2.清除闹钟的中断悬挂位(在此语句之前要加上RTC_WaitForLastTask();)
二者都要清除;要不然就会发生这样的事情:程序一直进中断,主程序不执行了
6.调试的时候,把printf函数多放几处,这样就可以通过串口看出程序到底执行到什么地方了
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。安全检查中...
请打开浏览器的javascript,然后刷新浏览器
< 浏览器安全检查中...
还剩 5 秒&温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!&&|&&
LOFTER精选
网易考拉推荐
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
以下程序作者为“ jjldc (九九)“rtc_time.h#ifndef _RTC_TIME_H_#define _RTC_TIME_H_#include &time.h&extern struct tm Time_ConvUnixToCalendar(time_t t);extern time_t Time_ConvCalendarToUnix(struct tm t);extern time_t Time_GetUnixTime(void);extern struct tm Time_GetCalendarTime(void);extern void Time_SetUnixTime(time_t);extern void Time_SetCalendarTime(struct tm t);#endifrtc_time.c/******************************************************************************** 本文件实现基于RTC的日期功能,提供年月日的读写。(基于ANSI-C的time.h)* * 作者:jjldc (九九)* QQ: * * RTC中保存的时间格式,是UNIX时间戳格式的。即一个32bit的time_t变量(实为u32)** ANSI-C的标准库中,提供了两种表示时间的数据
型:* time_t:
UNIX时间戳(从起到某时间经过的秒数)*
typedef unsigned int time_t;* * struct tm: Calendar格式(年月日形式)*
tm结构如下:*
struct tm {*
// 秒 seconds after the minute, 0 to 60*
(0 - 60 allows for the occasional leap second)*
// 分 minutes after the hour, 0 to 59*
// 时 hours since midnight, 0 to 23*
// 日 day of the month, 1 to 31*
// 月 months since January, 0 to 11*
// 年 years since 1900*
// 星期 days since Sunday, 0 to 6*
// 从元旦起的天数 days since January 1, 0 to 365*
int tm_ // 夏令时??Daylight Savings Time flag*
其中wday,yday可以自动产生,软件直接读取*
mon的取值为0-11* ***注意***:* tm_year:在time.h库中定义为1900年起的年份,即2008年应表示为8*
这种表示方法对用户来说不是十分友好,与现实有较大差异。*
所以在本文件中,屏蔽了这种差异。*
即外部调用本文件的函数时,tm结构体类型的日期,tm_year即为2008*
注意:若要调用系统库time.c中的函数,需要自行将tm_year-=1900* * 成员函数说明:* struct tm Time_ConvUnixToCalendar(time_t t);*
输入一个Unix时间戳(time_t),返回Calendar格式日期* time_t Time_ConvCalendarToUnix(struct tm t);*
输入一个Calendar格式日期,返回Unix时间戳(time_t)* time_t Time_GetUnixTime(void);*
从RTC取当前时间的Unix时间戳值* struct tm Time_GetCalendarTime(void);*
从RTC取当前时间的日历时间* void Time_SetUnixTime(time_t);*
输入UNIX时间戳格式时间,设置为当前RTC时间* void Time_SetCalendarTime(struct tm t);*
输入Calendar格式时间,设置为当前RTC时间* * 外部调用实例:* 定义一个Calendar格式的日期变量:** now.tm_year = 2008;* now.tm_mon = 11;
//12月* now.tm_mday = 20;* now.tm_hour = 20;* now.tm_min = 12;* now.tm_sec = 30;* * 获取当前日期时间:* tm_now = Time_GetCalendarTime();* 然后可以直接读tm_now.tm_wday获取星期数* * 设置时间:* Step1. tm_now.xxx =* Step2. Time_SetCalendarTime(tm_now);* * 计算两个时间的差* struct tm t1,t2;* t1_t = Time_ConvCalendarToUnix(t1);* t2_t = Time_ConvCalendarToUnix(t2);* dt = t1_t - t2_t;* dt就是两个时间差的秒数* dt_tm = mktime(dt); //注意dt的年份匹配,ansi库中函数为相对年份,注意超限* 另可以参考相关资料,调用ansi-c库的格式化输出等功能,ctime,strftime等* *******************************************************************************//* Includes ------------------------------------------------------------------*/#include "stm32f10x_lib.h"#include "RTC_Time.h"/* Private typedef -----------------------------------------------------------*//* Private define ------------------------------------------------------------*//* Private macro -------------------------------------------------------------*//* Private variables ---------------------------------------------------------*//* Private function prototypes -----------------------------------------------*/void Time_Set(u32 t);/* Private functions ---------------------------------------------------------*//******************************************************************************** Function Name
: Time_ConvUnixToCalendar(time_t t)* Description
: 转换UNIX时间戳为日历时间* Input
当前时间的UNIX时间戳* Output
: None* Return
: struct tm*******************************************************************************/struct tm Time_ConvUnixToCalendar(time_t t){ struct tm *t_ t_tm = localtime(&t); t_tm-&tm_year += 1900; //localtime转换结果的tm_year是相对值,需要转成绝对值 return *t_}/******************************************************************************** Function Name
: Time_ConvCalendarToUnix(struct tm t)* Description
: 写入RTC时钟当前时间* Input
: struct tm t* Output
: None* Return
: time_t*******************************************************************************/time_t Time_ConvCalendarToUnix(struct tm t){ t.tm_year -= 1900;
//外部tm结构体存储的年份为2008格式
//而time.h中定义的年份格式为1900年开始的年份
//所以,在日期转换时要考虑到这个因素。 return mktime(&t);}/******************************************************************************** Function Name
: Time_GetUnixTime()* Description
: 从RTC取当前时间的Unix时间戳值* Input
: None* Output
: None* Return
: time_t t*******************************************************************************/time_t Time_GetUnixTime(void){ return (time_t)RTC_GetCounter();}/******************************************************************************** Function Name
: Time_GetCalendarTime()* Description
: 从RTC取当前时间的日历时间(struct tm)* Input
: None* Output
: None* Return
: time_t t*******************************************************************************/struct tm Time_GetCalendarTime(void){ time_t t_t; struct tm t_ t_t = (time_t)RTC_GetCounter(); t_tm = Time_ConvUnixToCalendar(t_t); return t_}/******************************************************************************** Function Name
: Time_SetUnixTime()* Description
: 将给定的Unix时间戳写入RTC* Input
: time_t t* Output
: None* Return
: None*******************************************************************************/void Time_SetUnixTime(time_t t){
PWR_BackupAccessCmd(ENABLE); RTC_WaitForLastTask(); RTC_SetCounter((u32)t); RTC_WaitForLastTask(); PWR_BackupAccessCmd(DISABLE);}/******************************************************************************** Function Name
: Time_SetCalendarTime()* Description
: 将给定的Calendar格式时间转换成UNIX时间戳写入RTC* Input
: struct tm t* Output
: None* Return
: None*******************************************************************************/void Time_SetCalendarTime(struct tm t){ Time_SetUnixTime(Time_ConvCalendarToUnix(t));}
阅读(8102)|
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
历史上的今天
在LOFTER的更多文章
loftPermalink:'',
id:'fks_',
blogTitle:'STM32 RTC日历程序',
blogAbstract:'STM32的RTC只是一个32bit 计数器,没有年月日星期等信息,比起专用RTC芯片那差很远。要实现时间日期功能,要程序实现。记得linux下面的时间也是一个32bit的计数器。一查,原来网上牛人多的是,早已实现。而且用此法实现,非常简单。完全不用考虑什么闰年,大小月等。关键函数mktime,标准函数库函数。以下程序作者为“ jjldc (九九)“rtc_time.h#ifndef _RTC_TIME_H_#define _RTC_TIME_H_#include &time.h&extern struct tm Time_ConvUnixToCalendar(time_t t);',
blogTag:'',
blogUrl:'blog/static/',
isPublished:1,
istop:false,
modifyTime:3,
publishTime:1,
permalink:'blog/static/',
commentCount:1,
mainCommentCount:1,
recommendCount:2,
bsrk:-100,
publisherId:0,
recomBlogHome:false,
currentRecomBlog:false,
attachmentsFileIds:[],
groupInfo:{},
friendstatus:'none',
followstatus:'unFollow',
pubSucc:'',
visitorProvince:'',
visitorCity:'',
visitorNewUser:false,
postAddInfo:{},
mset:'000',
remindgoodnightblog:false,
isBlackVisitor:false,
isShowYodaoAd:false,
hostIntro:'',
hmcon:'1',
selfRecomBlogCount:'0',
lofter_single:''
{list a as x}
{if x.moveFrom=='wap'}
{elseif x.moveFrom=='iphone'}
{elseif x.moveFrom=='android'}
{elseif x.moveFrom=='mobile'}
${a.selfIntro|escape}{if great260}${suplement}{/if}
{list a as x}
推荐过这篇日志的人:
{list a as x}
{if !!b&&b.length>0}
他们还推荐了:
{list b as y}
转载记录:
{list d as x}
{list a as x}
{list a as x}
{list a as x}
{list a as x}
{if x_index>4}{break}{/if}
${fn2(x.publishTime,'yyyy-MM-dd HH:mm:ss')}
{list a as x}
{if !!(blogDetail.preBlogPermalink)}
{if !!(blogDetail.nextBlogPermalink)}
{list a as x}
{if defined('newslist')&&newslist.length>0}
{list newslist as x}
{if x_index>7}{break}{/if}
{list a as x}
{var first_option =}
{list x.voteDetailList as voteToOption}
{if voteToOption==1}
{if first_option==false},{/if}&&“${b[voteToOption_index]}”&&
{if (x.role!="-1") },“我是${c[x.role]}”&&{/if}
&&&&&&&&${fn1(x.voteTime)}
{if x.userName==''}{/if}
网易公司版权所有&&
{list x.l as y}
{if defined('wl')}
{list wl as x}{/list}2013年1月 硬件/嵌入开发大版内专家分月排行榜第一2012年10月 硬件/嵌入开发大版内专家分月排行榜第一2012年9月 硬件/嵌入开发大版内专家分月排行榜第一2012年8月 硬件/嵌入开发大版内专家分月排行榜第一2012年7月 硬件/嵌入开发大版内专家分月排行榜第一2012年6月 硬件/嵌入开发大版内专家分月排行榜第一2012年5月 硬件/嵌入开发大版内专家分月排行榜第一2012年4月 硬件/嵌入开发大版内专家分月排行榜第一2012年3月 硬件/嵌入开发大版内专家分月排行榜第一2012年2月 硬件/嵌入开发大版内专家分月排行榜第一2012年1月 硬件/嵌入开发大版内专家分月排行榜第一2011年11月 硬件/嵌入开发大版内专家分月排行榜第一2011年10月 硬件/嵌入开发大版内专家分月排行榜第一2011年9月 硬件/嵌入开发大版内专家分月排行榜第一
2014年10月 硬件/嵌入开发大版内专家分月排行榜第二2014年2月 硬件/嵌入开发大版内专家分月排行榜第二2013年10月 硬件/嵌入开发大版内专家分月排行榜第二2013年8月 硬件/嵌入开发大版内专家分月排行榜第二2013年3月 硬件/嵌入开发大版内专家分月排行榜第二2012年12月 硬件/嵌入开发大版内专家分月排行榜第二2012年11月 硬件/嵌入开发大版内专家分月排行榜第二2011年12月 硬件/嵌入开发大版内专家分月排行榜第二
2013年4月 硬件/嵌入开发大版内专家分月排行榜第二2007年9月 硬件/嵌入开发大版内专家分月排行榜第二
2013年5月 硬件/嵌入开发大版内专家分月排行榜第三2012年9月 硬件/嵌入开发大版内专家分月排行榜第三2007年11月 硬件/嵌入开发大版内专家分月排行榜第三
本帖子已过去太久远了,不再提供回复功能。stm32 RTC问题
来源:csdn
【void RTC_Config(void)
//我们在BKP的后备寄存器1中,存了一个特殊字符0xA5A5
//第一次上电或后备电源掉电后,该寄存器数据丢失,
//表明RTC数据丢失,需要重新配置
if (BKP_ReadBackupRegister(BKP_DR1) != 0x0505)
//重新配置RTC
RTC_Configuration();
RTC_Set(,13,41,25);
// Time_Set(23,59,59);
//配置完成后,向后备寄存器中写特殊字符0xA5A5
BKP_WriteBackupRegister(BKP_DR1, 0x0505);
//若后备寄存器没有掉电,则无需重新配置RTC
//这里我们可以利用RCC_GetFlagStatus()函数查看本次复位类型
if (RCC_GetFlagStatus(RCC_FLAG_PORRST) != RESET)
//这是上电复位
else if (RCC_GetFlagStatus(RCC_FLAG_PINRST) != RESET)
//这是外部RST管脚复位
//清除RCC中复位标志
RCC_ClearFlag();
//虽然RTC模块不需要重新配置,且掉电后依靠后备电池依然运行
//但是每次上电后,还是要使能RTCCLK???????
RCC_RTCCLKCmd(ENABLE);
//等待RTC时钟与APB1时钟同步
RTC_WaitForSynchro();
//使能秒中断
RTC_ITConfig(RTC_IT_SEC, ENABLE);
//等待操作完成
RTC_WaitForLastTask();
/* Enable PWR and BKP clocks */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
/* Allow access to BKP Domain */
PWR_BackupAccessCmd(ENABLE);
#ifdef RTCClockOutput_Enable
/* Disable the Tamper Pin */
BKP_TamperPinCmd(DISABLE);
/* Enable RTC Clock Output on Tamper Pin */
BKP_RTCOutputConfig(BKP_RTCOutputSource_CalibClock);
这是我从网上下载的代码,功能也实现了,但是还是有一个疑惑,我感觉在上电复位以后对rtc配置一次就够了,然后设置时间,在RTC_Set(,13,41,25);函数以后,我感觉就都不需要了。不知道这样理解对不对?】
falloutmx:
else那些是为了完备性
woshi_ziyu:
/第一次上电或后备电源掉电后设置时间
这是我从网上下载的代码,功能也实现了,但是还是有一个疑惑,我感觉在上电复位以后对rtc配置一次就够了,然后设置时间,在RTC_Set(,13,41,25);函数以后,我感觉就都不需要了。不知道这样理解对不对?
要看有没有完全掉电。。。
掉电后,数据会丢
如果确定不掉,理论上,那当然是设置一次就可以了
zhangbb326:
0XA5A5是什么意思为什么要写入0XA5A5啊?
zhangbb326:
0xA5A5这个只是标志而已,是用来确认RTC的时钟是否已经设置好了。跟硬件无关。
第一次使用rtc时,没有设置过时钟,那么备份域的这个寄存器就不会等于0xa5a5,
于是执行RTC_Configuration()来配置时钟。
在设置了时钟之后 ,向备份域寄存器写入0xa5a5,表明时钟已经配置过了。
所以,这里的0xa5a5你可以用其它的数值。只要写入数的跟用来判定的是同一个数就可以了。(终于找到了,这是转的别人的,不懂的也看一下吧。)
免责声明:本站部分内容、图片、文字、视频等来自于互联网,仅供大家学习与交流。相关内容如涉嫌侵犯您的知识产权或其他合法权益,请向本站发送有效通知,我们会及时处理。反馈邮箱&&&&。
学生服务号
在线咨询,奖学金返现,名师点评,等你来互动}

我要回帖

更多关于 stm32f030 rtc 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信