stc32G库函数(三)——RTC实时时钟

本文介绍了在STC32G12K128单片机上使用RTC实时时钟的功能和初始化过程,包括设置RTC时间、读取时间、修改时间的函数实现。作者提到使用内部32kHz时钟可能存在误差,并建议使用外部32.768kHz晶振以提高精度。此外,文章还讨论了单片机是否能同时运行不同频率的时钟以及RTC在断电后的特性。在实践中,作者遇到的挑战是确认RTC时钟与主时钟共存时的准确性。
摘要由CSDN通过智能技术生成

最近在用stc32g12k128单片机做一款手表,在阅读芯片手册时发现这款芯片拥有rtc实时时钟的功能,所以就直接拿来用了。

首先,让我们先来看看这款芯片的rtc实时时钟有哪些功能:

 同样的,在这里我们也是使用STC32G的库函数,先将STC32G_RTC.c添加到工程文件中,然后新建一个文件存放rtc的相关操作函数,我写的函数如下:

u8 datetime[6]={0,0,0,10,25,0};

//========================================================================
// 函数: RTC_init
// 描述: 用户初始化程序.
// 参数: None.
// 返回: None.
// 版本: V1.0, 2020-09-25
//========================================================================
void RTC_init(void)
{
	RTC_InitTypeDef		RTC_InitStructure;

	RTC_InitStructure.RTC_Clock  = RTC_IRC32KCR;//RTC 时钟, RTC_IRC32KCR, RTC_X32KCR
	RTC_InitStructure.RTC_Enable = ENABLE;			//I2C功能使能,   ENABLE, DISABLE
	RTC_InitStructure.RTC_Year   = 22;					//RTC 年, 00~99, 对应2000~2099年
	RTC_InitStructure.RTC_Month  = 9;					//RTC 月, 01~12
	RTC_InitStructure.RTC_Day    = 23;					//RTC 日, 01~31
	RTC_InitStructure.RTC_Hour   = 22;					//RTC 时, 00~23
	RTC_InitStructure.RTC_Min    = 50;					//RTC 分, 00~59
	RTC_InitStructure.RTC_Sec    = 55;					//RTC 秒, 00~59
	RTC_InitStructure.RTC_Ssec   = 00;					//RTC 1/128秒, 00~127

	RTC_InitStructure.RTC_ALAHour= 00;					//RTC 闹钟时, 00~23
	RTC_InitStructure.RTC_ALAMin = 00;					//RTC 闹钟分, 00~59
	RTC_InitStructure.RTC_ALASec = 00;					//RTC 闹钟秒, 00~59
	RTC_InitStructure.RTC_ALASsec= 00;					//RTC 闹钟1/128秒, 00~127
	RTC_Inilize(&RTC_InitStructure);
//	NVIC_RTC_Init(RTC_ALARM_INT|RTC_SEC_INT,Priority_0);		//中断使能, RTC_ALARM_INT/RTC_DAY_INT/RTC_HOUR_INT/RTC_MIN_INT/RTC_SEC_INT/RTC_SEC2_INT/RTC_SEC8_INT/RTC_SEC32_INT/DISABLE; 优先级(低到高) Priority_0,Priority_1,Priority_2,Priority_3
}

void Get_time(u8 *datetime)
{
	datetime[0]=YEAR;
	datetime[1]=MONTH;
	datetime[2]=DAY;
	datetime[3]=HOUR;
	datetime[4]=MIN;
	datetime[5]=SEC;
}

void Write_RTC(u8 *new_datetime)
{
	INIYEAR = new_datetime[0];
	INIMONTH = new_datetime[1];
	INIDAY = new_datetime[2];

	INIHOUR = new_datetime[3];   //修改时分秒
	INIMIN = new_datetime[4];
	INISEC = new_datetime[5];
	INISSEC = 0;
	RTCCFG |= 0x01;   //触发RTC寄存器初始化
}

void Show_time(void)
{
	u8 show[4]={1,0,2,5};
	Get_time(datetime);
	
	show[0]=datetime[3]/10;
	show[1]=datetime[3]-show[0]*10;
	show[2]=datetime[4]/10;
	show[3]=datetime[4]-show[2]*10;
	
	OLED_ShowChar(24,2,show[0],32);
	OLED_ShowChar(40,2,show[1],32);
	OLED_ShowChar(56,2,10,32);
	OLED_ShowChar(72,2,show[2],32);
	OLED_ShowChar(88,2,show[3],32);
}

其中里面的YEAR,MONTH,DAY等是单片机的寄存器,可以直接读取;INIYEAR,INIMONTH,INIDAY等也是单片机的寄存器,不过是初始化rtc时钟用的;因为在作用过程中可能需要修改时间,所以我写了write_RTC函数,可以修改时间,输入参数为时间的数组。

最后就是一些自己在开发时的一些问题,在芯片手册时钟管理这一章提到使用内部32k时钟会误差比较大,我不清楚是用做主时钟时误差比较大,还是用做rtc时钟时误差比较大,或者说都会有误差,使用在使用时还是建议使用外部晶振,原理图也给出了:

我也有一个不能很好解决的问题,就是单片机不知道能不能同时启动两个不同频率的时钟,也就是说我在使用24Mhz为主时钟的同时,还选用32khz为rtc时钟。而我在使用rtc后,程序按照24Mhz的延时是没有错误,也就是说主时钟还是24Mhz,但是不知道这个判断方法准不准确,希望有路过的大佬答疑一下。

在最后,使用芯片内部的RTC实时时钟最大的好处就是可以节约成本了,而缺点也有,就是没有备用电源引脚,当单片机断电停止工作后时钟也会停止工作。 

经过我的使用,若使用外部32.768kHz的晶振作为RTC的时钟晶振,C1和C2的大小必须严格控制在20p~47p,同时我推荐是在20p到30p,若C的电容过大,可能会导致时钟初始化慢,或者初始化失败等的问题。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值