历史上的今天
今天是:2025年03月06日(星期四)
2019年03月06日 | 关于STM32使用RTC时复位后程序死在 RTC
2019-03-06 来源:eefocus
在软件仿真时如果不需要配置,则程序会死在 RTC_WaitForSynchro() 函数中。而下载到硬件上时,有时候可以跑,有时候也会在该函数中死循环。
可能的原因:
首先,一定要确认是否使能了对后备寄存器和RTC的访问。
系统复位后,对后备寄存器和RTC的访问被禁止,这是为了防止对后备区域(BKP)的意外写操作。执行以下操作将使能对后备寄存器和RTC的访问:
● 设置寄存器RCC_APB1ENR的PWREN和BKPEN位,使能电源和后备接口时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
● 设置寄存器PWR_CR的DBP位,使能对后备寄存器和RTC的访问
PWR_BackupAccessCmd(ENABLE);
另外还要使能RTC时钟 RCC_RTCCLKCmd(ENABLE); 虽然该函数的说明中说只在RCC_RTCCLKConfig()函数调用之后才能调用,但是实际上如果不调用该函数,仿真时就会在 RTC_WaitForSynchro() 函数中死循环,等待RTC时钟同步。
也就是说,不论是否需要配置RTC寄存器,每次系统复位都需要执行如下操作:
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);PWR_BackupAccessCmd(ENABLE);RCC_RTCCLKCmd(ENABLE);
其次,STM32的RTC对外部LSE要求比较高,最好使用负载电容为6pF的晶振。在芯片的DataSheet中有明确的说明,不能使用12.5pF的晶振。“ To avoid exceeding the maximum value of CL1 and CL2 (15 pF) it is strongly recommended to use a resonator with a load capacitance CL≤ 7 pF. Never use a resonator with a load
capacitance of 12.5 pF.”
参考代码:
#include "RTC.h"
__IO uint32_t TimeDisplay;
void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
NVIC_InitStructure.NVIC_IRQChannel=RTC_IRQn;
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_InitStructure.NVIC_IRQChannelSubPriority=0;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;
NVIC_Init(&NVIC_InitStructure);
}
void RTC_Config(void)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_BKP | RCC_APB1Periph_PWR,ENABLE);
PWR_BackupAccessCmd(ENABLE);
BKP_DeInit();
RCC_LSEConfig(RCC_LSE_ON);
while(RCC_GetFlagStatus(RCC_FLAG_HSERDY)==RESET){}
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
RCC_RTCCLKCmd(ENABLE);
RTC_WaitForSynchro();
RTC_WaitForLastTask();
RTC_ITConfig(RTC_IT_SEC,ENABLE);
RTC_WaitForLastTask();
RTC_SetPrescaler(32767);
RTC_WaitForLastTask();
}
void Time_Ajust(void)
{
RTC_WaitForLastTask();
RTC_SetCounter(Time_Regulate());
RTC_WaitForLastTask();
}
uint32_t Time_Regulate()
{
uint32_t temp_hour=0xff,temp_minute=0xff,temp_sec=0xff;
printf("Set hour:");
while(temp_hour==0xff){
USART_Scanf(23);
}
printf(" %d",temp_hour);
printf("Set minute:");
while(temp_minute==0xff){
USART_Scanf(59);
}
printf(" %d",temp_minute);
printf("Set second:");
while(temp_sec==0xff){
USART_Scanf(59);
}
printf(" %d",temp_sec);
return temp_hour*3600+temp_minute*60+temp_sec;
}
void RTC_Init(void)
{
if(BKP_ReadBackupRegister(BKP_DR1)==0xA5A5){
printf("\r\n This is a RTC demo! \r\n");
printf("\r\n RTC not yet configured \r\n");
RTC_Config();
Time_Ajust();
}
if(RCC_GetFlagStatus(RCC_FLAG_PORRST)!=RESET)
{
printf("\r\n not occured \r\n");
}
else if(RCC_GetFlagStatus(RCC_FLAG_PINRST)!=RESET)
{
printf("\r\n no need to config \r\n");
}
RTC_WaitForSynchro();
RTC_ITConfig(RTC_IT_SEC,ENABLE);
RTC_WaitForLastTask();
}
void Time_show(void)
{
printf("\r\n");
while(1){
if(TimeDisplay==0)
{
Time_Display(RTC_GetCounter());
TimeDisplay=1;
}
}
}
void Time_Display(uint32_t Timewar)
{
unsigned int min=0,hour=0,sec=0;
hour=Timewar/3600;
min=Timewar%3600/60;
sec=Timewar%60;
printf("%.2d:%.2d:%.2d",hour,min,sec);
}
uint8_t USART_Scanf(uint32_t value)
{
uint32_t index=0;
uint32_t temp[2]={0,0};
while(index<2){
while(USART_GetFlagStatus(USART1, USART_FLAG_RXNE)==RESET){}
temp[index]=USART_ReceiveData(USART1);
index++;
if(temp[index-1]
史海拾趣
|
本设计实例介绍如何在短暂电压不足期间使电信设备保持正常工作。首先必须了解电信设备专用电源的几个细节。向电信设备馈电的电源的共模电压为-48V,尽管实际电压范围可能是-42.5V ~ -56V、-40V ~ -60V,甚至超出这些范围。公共电源——“砖块”DC/D ...… 查看全部问答> |
|
关于我自己 1、业务员和客户聊天的时候哪些话题不需要聊太多关于技术和理论的话题,需要的是今天的新闻呀、天气呀等话题。因此,业务员在日常的时候必须多读些有关经济、销售方面的书籍、杂志,尤其必须每天阅读报纸,了解国家、社会消 ...… 查看全部问答> |
|
请问WINCE 打印一般用哪些类来实现? 可以用CPrintDialog类吗,我在VS2005中为什么编译会出现\'CPrintDialog\' : undeclared identifier?… 查看全部问答> |
|
单位需要设计一种ISA转PCI的接口卡 用途是把以前老设备上面的ISA接口卡(主要是s1240程控机)转用点现在PCI口上使用.通过查询资料,我发现用专用芯片pci9052 似乎是最省力的办法。但是由于本人学的是通信专业,对硬件设计基本不明白,数电模电忘记差 ...… 查看全部问答> |
|
WinCE5/6如何实现程序开机自动运行,并且程序可以运行配置的命令参数 [HKEY_LOCAL_MACHINE\\Init] \"Launch10\"=\"shell.exe\" \"Launch20\"=\"device.exe\" \"Launch30\"=\"gwes.dll\" \"Depend30\"=hex:14,00 \"Launch50\"=\"taskman.e ...… 查看全部问答> |
|
如题。 不是mobile. 一般在[HKEY_LOCAL_MACHINE]software\\apps下会有一些安装后软件的信息。 我已能获取到已安装软件的全部文件的详细路径信息和注册表信息。 但是不能得到该软件的主程序,也就是启动程序的exe的路径等信息,导致我没法利用这 ...… 查看全部问答> |
|
最近闲来无事,申请了个8bit的小板子玩玩,主要是上面有触摸按键,手头还有个液晶,所以就想结合起来搞点东西。说实在的,就是闲的。 先说着板子,前一段在某群接到可以申请最小系统的通知,要知道,这家的 ...… 查看全部问答> |
|
这样问也不知道冒不冒昧,但是还是得问问soso姐,姐姐,从我个人在论坛每个子模块查资料找东西来看,我觉得子模块有点乱,咱们能不能把子模块中的帖子细细分下类呢?比如说,软件和资料,我们把模块细化分一下类,新回复的东西还是固有不变,这样大 ...… 查看全部问答> |
|
128KB的Flash中我存储了两段程序 第一个基址是0x00000000 第二个基址是0x00001000 这两个程序是不相关的,独立的, 第一个程序我是用新唐的ICP软件下载的,第二个程序是我通过自己写在LDROM中的程序下载到0x00001000 , 现在我希望能够 ...… 查看全部问答> |




