今天早上进行产品测试的时候突然发现我的ds1302的数据不对了,每次秒走一会跳一会,这让我很纳闷,我说着个问题真心蹊跷,
我就想了,我使用的芯片内置了一个rtc这里刚好可以以用上,就花了几个小时看了看资料,以前用过103的rtc,一看感觉407的比
103的复杂很多了,开始感觉挺茫然的,还是老样子拿出datasheet看了一下,当然了就我的英文水品想每个字看懂真心困难,所以
就在网上看了一些别人的心得,我操真心写的很好,但大多都是我这个调试的有问题了怎么想办法发把他解决玩了,还有就是有问题
请联系我啊,我靠,谁有这心情啊,还是自己动手吧,其实如果使用stm32如果不涉及到寄存器这种对芯片内部的结构了解很深的情况下
我们使用st自带的固件库,使用api方式来调用代码,还是比较容易参透的,这就需要有耐心,还有c语言一定的过关。。。呵呵,不多说额
这个配置也就三步,
STM32的RTC时钟配置因为涉及了许多的寄存器,如:BKP、PWR、RTC,弄得很杂乱,现
在由我来做个RTC配置的总结。
RTC简介:RTC是一个实时时钟是一个独立的定时器,RTC模块拥有一组连续计数的计数器,
在相应软件配置下,可以提供时钟、日历的功能。修改计数器的值可以重新设置系统当前的
时间和日期。
配置RTC前需知:
BKP:
RTC模块和时钟配置系统的寄存器是在后备区域的(即BKP),通过BKP后备区域来存储RTC
配置的数据可以让在系统复位或待机模式下唤醒后RTC里面配置的数据维持不变。
PWR:
PWR为电源的寄存器,我们需要用到的是电源控制寄存器(PWR_CR),通过使能PWR_CR的DBP
位来取消后备区域BKP的写保护。
RTC:
由一组可编程计数器组成,分成两个主要模块。第一个模块是RTC的预分频
模块,它可编程产生最长为1秒的RTC时间基准TR_CLK。RTC的预分频模块包含了一个20
位的
可编程分频器(RTC预分频器)。如果在RTC_CR寄存器中设置了相应的允许位,则在每个实
时时钟(RTC)TR_CLK周期中RTC产生一个中断(秒中断)。第二个模块是一个32位的可编
程计数器,可被初始
化为当前的系统时间。系统时间按TR_CLK周期累加并与存储在RTC_ALR寄存器中的可编程
时
间相比较,如果RTC_CR控制寄存器中设置了相应允许位,比较匹配时将产生一个闹钟中断。
第一步:通过设置寄存器RCC_APB1ENR的PWREN和BKPEN位来打开电源和后备接口的时钟
调用库函数:
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR| RCC_APB1Periph_BKP,ENABLE);
第二步:电源控制寄存器(PWR_CR)的DBP位来使能对后备寄存器和RTC的访问
调用库函数:
PWR_BackupAccessCmd(ENABLE);
第三步:初始化复位BKP寄存器
调用库函数:
BKP_DeInit();
第四步:设置RTCCLK
1. 查询RTOFF位,直到RTOFF的值变为’1’
2. 置CNF值为1,进入配置模式
3. 对一个或多个RTC寄存器进行写操作
4. 清除CNF标志位,退出配置模式
5. 查询RTOFF,直至RTOFF位变为’1’以确认写操作已经完成。
仅当CNF标志位被清除时,写操作才能进行,这个过程至少需要3个RTCCLK周期。
代码如下,仅供参考
void RTC_Config(void) //??????????rtc
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
PWR_BackupAccessCmd(ENABLE);
RCC_LSEConfig(RCC_LSE_ON);
while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)
{
}
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
SynchPrediv = 0xFF;
AsynchPrediv = 0x7F;
RCC_RTCCLKCmd(ENABLE);
RTC_WaitForSynchro();
// RTC_TimeStampCmd(RTC_TimeStampEdge_Falling, ENABLE);
}
void RTC_init(void)
{
RTC_InitTypeDef RTC_InitStructure;
RTC_Config();
RTC_InitStructure.RTC_AsynchPrediv = AsynchPrediv;
RTC_InitStructure.RTC_SynchPrediv = SynchPrediv;
RTC_InitStructure.RTC_HourFormat = RTC_HourFormat_24;
RTC_Init(&RTC_InitStructure);
}
void Set_RTC_Time(u16 year,u8 month,u8 day, u8 hour,u8 minute,u8 second)
{
RTC_TimeTypeDef RTC_TimeStructure;
RTC_DateTypeDef RTC_DateStructure;
RTC_TimeStructure.RTC_Hours=hour;
RTC_TimeStructure.RTC_Minutes=minute;
RTC_TimeStructure.RTC_Seconds=second;
// RTC_DateStructure.RTC_Year=year;
RTC_DateStructure.RTC_Year=year;
RTC_DateStructure.RTC_Month=month;
RTC_DateStructure.RTC_Date=day;
RTC_DateStructure.RTC_WeekDay=0;
while (RTC_SetTime(RTC_Format_BCD,&RTC_TimeStructure)==ERROR ){};
while (RTC_SetDate(RTC_Format_BCD,&RTC_DateStructure)==ERROR){};
}
阅读(14496) | 评论(0) | 转发(3) |