STM32设备之RTC编程(二)<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
一、程序编写流程
1、命令处理程序的修改
首先在命令处理表里添加相应的命令“time”和处理命令函数“CmdTime”。
char* CmdStrTable[5]={
"help","cls","ledon","ledoff",
"time"
};
CmdTable[0].CmdFunc=CmdHelp;
CmdTable[1].CmdFunc=CmdCls;
CmdTable[2].CmdFunc=CmdLedOn;
CmdTable[3].CmdFunc=CmdLedOff;
CmdTable[4].CmdFunc=CmdTime;
在shell里的工作就算完成了,现在shell能识别命令time了。
2、命令处理函数CmdTime的编写
void CmdTime(void){
u32 RTCCount; //用于获取RTC的当前计数
static TimeStruct CurrentTime; //时间结构定义,从RTC计数获取时间
RTCCount= RTC_GetCounter(); //获取RTC的当前计数
Time_Convert(RTCCount,&CurrentTime); //转换为具体时间
//利用库函数将时间转换为格式化
sprintf(s,"%0.2d:%0.2d:%0.2d",CurrentTime.Hour,CurrentTime.Minute,CurrentTime.Second);
Shell_PutStr(s); /*在屏幕上显示*/
Shell_PutStr("\n"); //换行,回到命令提示符
}
3、编写RTC.c文件,RTC相关的一次处理函数在这里定义
现在就一个函数
void Time_Convert(u32 Count, TimeStruct* CurrentTime) //时间格式转换
{
u32 TempTime;
TempTime=Count/3600; //获得小时
CurrentTime->Hour=(u8) TempTime;
TempTime=(Count%3600)/60; //计算得分钟数
CurrentTime->Minute=(u8) TempTime;
TempTime=(Count%3600) %60; //对应秒
CurrentTime->Second=(u8) TempTime; //写入结构
}
二、RTC设备的配置
1、配置说明
RTC在开发板断电的情况下也是在运行的,此时由VBAT供电。而且RTC要进行写入操作,还必须在电源控制寄存器使能相应位。
RTC在一次配置后就持续运行,为了表明RTC是否曾经运行,在备份域使用一个寄存器写入特殊数值,如果曾经配置过,就什么也不做;如果没有配置过,则使用相应的时间写入RTC,并在备份域做上标记。
2、时间配置程序编写流程
/*使用RTC时要使能电源控制和备份域的时钟*/
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_PWR, ENABLE);
void RTC_Config(void){
u32 RTCCount;
u8 s[9]="16:54:11";
if (BKP_ReadBackupRegister(BKP_DR1) !=0xAAAA ) //如果备份域没有标记
{
RTC_Init(); //对RTC进行初始化
RTCCount=Time_GetCountFromStr(s); //从时间串获取对应计数值
RTC_SetCounter(RTCCount); //将计数值写入RTC计数器
RTC_WaitForLastTask();
BKP_WriteBackupRegister(BKP_DR1, 0xAAAA);
}
Else //如果备份域标记过了,不用做什么工作。
{
RTC_WaitForSynchro(); //等待RTC时钟同步
RTC_WaitForLastTask(); //等待RTC写操作完成
RTC_ITConfig(RTC_IT_SEC, ENABLE); //使能RTC秒中断
RTC_WaitForLastTask();
}
}
以下是上面调用的RTC_Init()初始化程序
void RTC_Init() {
PWR_BackupAccessCmd(ENABLE); //使能备份域修改
BKP_DeInit(); //备份域复位
RCC_LSEConfig( RCC_LSE_ON ); //使用外部振荡源
while (RCC_GetFlagStatus (RCC_FLAG_LSERDY )== RESET ); //直到振荡源准备好
RCC_RTCCLKConfig (RCC_RTCCLKSource_LSE);
RCC_RTCCLKCmd (ENABLE); //使能RTC工作
RTC_WaitForSynchro(); //等待RTC时钟同步
RTC_WaitForLastTask(); //等待RTC写操作完成
RTC_ITConfig(RTC_IT_SEC, ENABLE); //使能RTC秒中断
RTC_WaitForLastTask();
RTC_SetPrescaler( 32767 ); //使用的时钟为32.768kHz。
RTC_WaitForLastTask();
}
三、测试和总结
将程序编译、下载,我的shell里面又新增了一个命令,输入time,显示当前时间。
第二天开机显示时间:34:23:11超过24小时,所以又添加了起动处理和中断处理部分。
起动处理:
else
{
PWR_BackupAccessCmd(ENABLE);
RTC_WaitForSynchro(); //等待RTC时钟同步
RTC_WaitForLastTask(); //等待RTC写操作完成
RTCCount=RTC_GetCounter();
while (RTCCount >= 0x00015180 ) //启动复位后,如果发现超过24小时
{RTCCount -= 0x00015180; //则减去24小时。
RTC_SetCounter(RTCCount); //将计数值写入RTC计数器
RTC_WaitForLastTask();
}
RTC_ITConfig(RTC_IT_SEC, ENABLE); //使能RTC秒中断
RTC_WaitForLastTask();
}
中断处理:
void RTC_IRQHandler(void){
if (RTC_GetITStatus (RTC_IT_SEC ) != RESET )
{ RTC_ClearITPendingBit ( RTC_IT_SEC );
RTC_WaitForLastTask();
if ( RTC_GetCounter() == 0x00015180 )
{ RTC_SetCounter(0x0);
RTC_WaitForLastTask();
}
}
}
用户377235 2014-12-3 11:59
你好: 借鉴你上面的程序:这句会出错,不知道在什么地方定义的,全盘搜索库也没有找到,能告知吗?谢谢! RTCCount=Time_GetCountFromStr(s); //从时间串获取对应计数值 出现错误: Error: L6218E: Undefined symbol Time_GetCountFromStr