以下是写的RTC部分程序,有点乱,但还能读懂。 问题1: 在进行RTC操作时,每次都要执行这个 RTC_WaitForLastTask()函数,在上电初始化时基本还行,但也会出现执行 RTC_WaitForLastTask();函数时不过的问题,就是RTOFF位一直为0,造成死循环。 问题2:假如上电初始化都正常通过了,在程序正常执行时进行校表,这时往RTC中写校表数据时还时还要执行 RTC_WaitForLastTask();函数,这时也会死循环,不是偶尔,而是每次都是死循环。
以上两点问题造成RTC部分工作一直耽误着,百思不得其解,望版主及广大网友帮忙解决一下。
#include "includes.h"
uint8 rtcdata[8]; const uint8 monthday[2][12] = {{31,28,31,30,31,30,31,31,30,31,30,31}, // 不润年 {31,29,31,30,31,30,31,31,30,31,30,31}}; // 润年
/************************************************************************* ** 备份时万年历数据函数 ** *****************************************************************************/ void bak_time(void) { BKP_WriteBackupRegister(BKP_DR2, (yearhdata << 8) | yearldata); BKP_WriteBackupRegister(BKP_DR3, (monthdata << 8) | daydata); BKP_WriteBackupRegister(BKP_DR4, (weekdata << 8) | hourdata); BKP_WriteBackupRegister(BKP_DR5, (mindata << 8) | secdata); }
/***************************************************************************** ** 上电时从备份寄存器中取出万年历数据,并进行计算。 ** ********************************************************************************/ void copy_time(void) { uint16 temp; temp = BKP_ReadBackupRegister(BKP_DR2); yearhdata = 20; yearldata = temp & 0x00ff; // 年备份 temp = BKP_ReadBackupRegister(BKP_DR3); monthdata = (temp & 0xff00) >>8; // 月备份 daydata = temp & 0x00ff; // 日备份 temp = BKP_ReadBackupRegister(BKP_DR4); weekdata = (temp & 0xff00) >> 8; // 星期备份 hourdata = temp & 0x00ff; // 时备份 temp = BKP_ReadBackupRegister(BKP_DR5); mindata = (temp & 0xff00)>>8; // 分备份 secdata = temp & 0x00ff; // 秒备份 get_rtc(); }
/*************************************************************************** ** 天加1函数 ** ****************************************************************************/ void dayadd(void) { daydata ++; weekdata = (weekdata+1)%7; if (daydata >= monthday[(yearldata%4)==0 ? 1:0][monthdata-1]) { daydata = 1; monthdata ++; if (monthdata >= 12) { yearldata ++; monthdata = 1; } } bak_time(); }
/*********************************************************************** ** 时钟初始化函数, ** *****************************************************************************/ void RTC_Init(void) { if(BKP_ReadBackupRegister(BKP_DR1) != 0xA5A5) { RTC_Configuration(); Time_Adjust(Time_Regulate()); BKP_WriteBackupRegister(BKP_DR1, 0xA5A5); bak_time(); } else RTC_WaitForSynchro(); copy_time(); }
/******************************************************************************* * Function Name : RTC_Configuration * Description : Configures the RTC. * Input : None * Output : None * Return : None *******************************************************************************/ void RTC_Configuration(void) { /* Enable PWR and BKP clocks */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE); /* Allow access to BKP Domain */ PWR_BackupAccessCmd(ENABLE);
/* Reset Backup Domain */ BKP_DeInit(); /* Enable LSE */ RCC_LSEConfig(RCC_LSE_ON); /* Wait till LSE is ready */ while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET) { }
/* Select LSE as RTC Clock Source */ RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
/* Enable RTC Clock */ RCC_RTCCLKCmd(ENABLE);
/* Wait for RTC registers synchronization */ RTC_WaitForSynchro();
/* Wait until last write operation on RTC registers has finished */ RTC_WaitForLastTask(); /* Enable the RTC Second */ //RTC_ITConfig(RTC_IT_SEC, ENABLE);
/* Wait until last write operation on RTC registers has finished */ //RTC_WaitForLastTask(); /* Set RTC prescaler: set RTC period to 1sec */ RTC_SetPrescaler(32767); /* RTC period = RTCCLK/RTC_PR = (32.768 KHz)/(32767+1) */ /* Wait until last write operation on RTC registers has finished */ RTC_WaitForLastTask(); }
/******************************************************************************* * Function Name : Time_Regulate * Description : Returns the time entered by user, using Hyperterminal. * Input : None * Output : None * Return : Current time RTC counter value *******************************************************************************/ INT32U Time_Regulate(void) { /* Return the value to store in RTC counter register */ // yearhdata = 20; //2009年1月1日星期4,0点0分0秒. // yearldata = 9; // monthdata = 12; // daydata = 31; // weekdata = 4; // hourdata = 0; // mindata = 0; // secdata = 0; return((hourdata*3600 + mindata*60 + secdata)); }
/******************************************************************************* * Function Name : Time_Adjust * Description : Adjusts time. * Input : None * Output : None * Return : None *******************************************************************************/ void Time_Adjust(uint32 data) { /* Wait until last write operation on RTC registers has finished */ RTC_WaitForLastTask(); /* Change the current time */ RTC_SetCounter(data); /* Wait until last write operation on RTC registers has finished */ RTC_WaitForLastTask(); }
/******************************************************************* ** 取得RTC的时间,并进行相关的计算. ** ** **************************************************************************/ void get_rtc(void) { uint8 temp; uint32 rtctemp; rtctemp = RTC_GetCounter(); if (rtctemp > 86399) { //RTC_SetCounter(rtctemp%86400); Time_Adjust(rtctemp%86400); temp = rtctemp/86400; rtctemp %= 86400; while(temp > 0) { temp --; dayadd(); // 天数加1. } } hourdata = rtctemp/3600; /* Compute hours */ mindata = (rtctemp % 3600)/60; /* Compute minutes */ secdata = (rtctemp % 3600)% 60; /* Compute seconds */ } |