关于STM32使用RTC时复位后程序死在 RTC
在軟件仿真時如果不需要配置,則程序會死在 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]<0x30||temp[index-1]>0x39){
printf("Please enter number between 0 and 9..");
index--;
}?
}
index=(temp[0]-0x30)*10+(temp[1]-0x30);?
if(index>value){
printf("Please enter number between 0 and %d",value);
return 0xff;
}
return value;
}
總結
以上是生活随笔為你收集整理的关于STM32使用RTC时复位后程序死在 RTC的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 纠结的STM32 RTC时钟源LSE
- 下一篇: RTC_WaitForSynchro()