1. 原理
1.1RTC框图
1.2 RTC基本结构
2. C标准库<time.h>的使用
#include <stdio.h>
#include <time.h>
/******此处定义的内容皆为time.h中的数据类型******/
time_t time_cnt; //64位int类型
struct tm time_date; //struct tm是一个整体表示结构体
char *time_str;
int main (void)
{
//time_cnt = time(NULL);
//time(&time_cnt); //此处作用与上行作用一致
time_cnt = 1672588795;
printf("%d\n",time_cnt);
/*****gmtime******
time_date = *gmtime(&time_cnt);
printf("%d\n",time_date.tm_year + 1900);
printf("%d\n",time_date.tm_mon + 1);
printf("%d\n",time_date.tm_mday );
printf("%d\n",time_date.tm_hour );
printf("%d\n",time_date.tm_min);
printf("%d\n",time_date.tm_sec);
printf("%d\n",time_date.tm_wday);
*/
/*localtime,此函数会自动添加偏移*/
time_date = *localtime(&time_cnt);
printf("%d\n",time_date.tm_year + 1900);
printf("%d\n",time_date.tm_mon + 1);
printf("%d\n",time_date.tm_mday );
printf("%d\n",time_date.tm_hour );
printf("%d\n",time_date.tm_min);
printf("%d\n",time_date.tm_sec);
printf("%d\n",time_date.tm_wday);
/*mktime 将时间转换为秒*/
time_cnt = mktime(&time_date);
printf("%d\n",time_cnt);
/*ctime 将秒转换成时间的字符串*/
time_str = ctime(&time_cnt);
printf(time_str);
/*asctime 将秒转换成时间的字符串,函数参数不一样*/
time_str = asctime(&time_date);
printf(time_str);
/*strftime 将秒转换成时间的字符串,格式为自定义,上面两个函数都是固定为默认的格式*/
char t[50];
strftime(t, 50, "%H-%M-%S", &time_date);
printf(t);
return 0;
}
3.Read&Write Backup Register
3.1 接线图
3.2实现代码
main.c
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "OLED.h"
#include "Key.h"
uint8_t KeyNum;
uint16_t ArrayWrite[] = {0X1234, 0X5678};
uint16_t ArrayRead[2];
int main(void)
{
OLED_Init();
Key_Init();
OLED_ShowString(1, 1, "W:");
OLED_ShowString(2, 1, "R:");
/***************Start Init**************/
RCC_APB1PeriphClockCmd(RCC_APB1Periph_BKP, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
PWR_BackupAccessCmd(ENABLE);
/***************Init End**************/
//BKP_WriteBackupRegister(BKP_DR1, 0X1234);
//OLED_ShowHexNum(1, 1, (BKP_ReadBackupRegister(BKP_DR1)), 4);
while(1)
{
KeyNum = Key_GetNum();
if(KeyNum == 1)
{
ArrayWrite[0] ++;
ArrayWrite[1] ++;
BKP_WriteBackupRegister(BKP_DR1, ArrayWrite[0]);
BKP_WriteBackupRegister(BKP_DR2, ArrayWrite[1]);
OLED_ShowHexNum(1, 3, ArrayWrite[0], 4);
OLED_ShowHexNum(1, 8, ArrayWrite[1], 4);
}
ArrayRead[0] = BKP_ReadBackupRegister(BKP_DR1);
ArrayRead[1] = BKP_ReadBackupRegister(BKP_DR2);
OLED_ShowHexNum(2, 3, ArrayRead[0], 4);
OLED_ShowHexNum(2, 8, ArrayRead[1], 4);
}
}
4. RTC(Real Time Clock)
4.1 接线图
4.2 实现代码
4.2.1 MyRTC.c
#include "stm32f10x.h" // Device header
#include <time.h>
uint16_t MyRTC_Time[] = {2024, 2, 2, 20, 18, 55};
void MyRTC_SetTime(void);//下方函数会用到该函数,该函数位置在后面,不在此声明下方函数会报错
void MyRTC_Init(void)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_BKP, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
PWR_BackupAccessCmd(ENABLE);
if(BKP_ReadBackupRegister(BKP_DR1) != 0XA5A5) //主电源和vbat同时断电,重新设置秒数.
{
RCC_LSEConfig(RCC_LSE_ON);
while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) != SET);
//选择时钟
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
RCC_RTCCLKCmd(ENABLE);
//等待同步,等待上一次函数写入完成.两个函数里面是执行等待
RTC_WaitForSynchro();
RTC_WaitForLastTask();
//两个函数的目的是防止时钟不同步造成的bug
RTC_SetPrescaler(32768 - 1); //写操作后这个值并不是立即生效,最好等待一下写操作完成
RTC_WaitForLastTask();
// RTC_SetCounter(1672588795); //设置初始时间,不写值默认为1970年
// RTC_WaitForLastTask();
MyRTC_SetTime();
BKP_WriteBackupRegister(BKP_DR1, 0XA5A5);
}
else
{
RTC_WaitForSynchro();
RTC_WaitForLastTask();
}
}
void MyRTC_SetTime(void)
{
time_t time_cnt;
struct tm time_date;
time_date.tm_year = MyRTC_Time[0] - 1900;
time_date.tm_mon = MyRTC_Time[1] - 1;
time_date.tm_mday = MyRTC_Time[2];
time_date.tm_hour = MyRTC_Time[3];
time_date.tm_min = MyRTC_Time[4];
time_date.tm_sec = MyRTC_Time[5];
time_cnt = mktime(&time_date) - 8 * 60 * 60;
RTC_SetCounter(time_cnt);
RTC_WaitForLastTask();
}
void MyRTC_ReadTime(void)
{
time_t time_cnt;
struct tm time_date;
time_cnt = RTC_GetCounter() + 8 * 60 *60;
time_date = *localtime(&time_cnt);
MyRTC_Time[0] = time_date.tm_year + 1900;
MyRTC_Time[1] = time_date.tm_mon + 1;
MyRTC_Time[2] = time_date.tm_mday;
MyRTC_Time[3] = time_date.tm_hour;
MyRTC_Time[4] = time_date.tm_min;
MyRTC_Time[5] = time_date.tm_sec;
}
4.2.2 main.c
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "OLED.h"
#include "MyRTC.h"
int main(void)
{
OLED_Init();
MyRTC_Init();
OLED_ShowString(1, 1, "Data:XXXX-XX-XX");
OLED_ShowString(2, 1, "Time:XX:XX:XX");
OLED_ShowString(3, 1, "CNT :");
OLED_ShowString(4, 1, "DIV :"); //DIV没自减一轮,CNT+1.
while(1)
{
MyRTC_ReadTime();
OLED_ShowNum(1, 6, MyRTC_Time[0], 4);
OLED_ShowNum(1, 11, MyRTC_Time[1], 2);
OLED_ShowNum(1, 14, MyRTC_Time[2], 2);
OLED_ShowNum(2, 6, MyRTC_Time[3], 2);
OLED_ShowNum(2, 9, MyRTC_Time[4], 2);
OLED_ShowNum(2, 12, MyRTC_Time[5], 2);
OLED_ShowNum(3, 6, RTC_GetCounter(), 10) ;
OLED_ShowNum(4, 6, RTC_GetDivider(), 10) ;
//OLED_ShowNum(4, 6, (32767 - RTC_GetDivider()) / 32737.0 * 999, 10) ; // 表示毫秒
}
}