软件模拟RTC功能在单片机上的C语言实现

1.前言

最近做到的项目有用到RTC这一功能模块,但是所用的单片机自身不带硬件RTC.所以需要软件模拟一个RTC模块,实现日期更迭功能。
所谓的RTC,即 real time clock,实时时钟系统,通过该模块可以一直获得当前实际的年月日,时分秒,星期的值。rtc模块可以自动实现日期更迭,月份更迭,年份更迭。
下面介绍第一种软件实现rtc模块的设计方法。

2.设计实现

想要实现软件rtc模块,首先单片机本身硬件资源要具备一个最少ms级别的精准的定时器,然后单片机本身跟其它设备之间有通讯接口,可以获得一次当前实时时间,以用来对自身的rtc时间进行校准。该通讯接口可以有很多种形式,比如单片机与手机app之间通过蓝牙通信,手机app获取到当前准确的时间后,通过自定的通讯协议下发到单片机端,单片机接收到了确切的当前时间后,将自身的rtc值校准为当前时间,后续就不用继续校准了。单片机可以用过自身的rtc模块一直维护更迭一个最新的当前日期时间。

第一种设计思想为,单片机端只维护更新一个相对时间,所谓相对时间,可以设计为2020年1月1日距今为止的相对天数,比如单片机端从通讯接口处获得了当前时间为2020年2月1号1点0分0秒,则通过转换函数1将日期转换为相对值32,然后更新到单片机rtc模块端,。命名此函数为Rtc_EncodeTim();后续r如果单片机需要把当前的相对时间转换为绝对日期时间,再通过转换函数2,将系统中的相对时间,转为当前现实世界的绝对日期值。将转换函数2命名为Rtc_DecodeTim();

下面贴几部分组成代码。

2.1结构体定义

typedef struct
{
    uint16_t year;
    uint8_t month;
    uint8_t day;
    uint8_t hour;     		
    uint8_t min;      
    uint8_t sec;
} ST_ABSOTIM;//绝对时间值结构体


typedef struct urtcType
{
    uint16_t day;
    uint8_t hour;     		
    uint8_t min;      
    uint8_t sec;
    unsigned long clock;

    unsigned char initedFlg;
} urtcType;//用于系统内部处理的相对时间结构体
urtcType urtc_time1;//定义rtc结构体对象

2.2通过硬件定时器实现时分秒日期的更新

//结构体初始化函数
void URTC_INIT(uint16_t day,uint8_t hour,uint8_t min,uint8_t sec )
{
    urtc_time1.day=day;
    urtc_time1.hour = hour;
    urtc_time1.min  =min;
    urtc_time1.sec  =sec;
    urtc_time1.clock = hour*3600+min*60+sec;
  
	//设置标志位为未初始化,向涂鸦模块发送串口命令请求初始化
	urtc_time1.initedFlg=0;
}
//用于更新rtc时间,通过硬件定时器1s调用一次即可
void Urtc_loop()
{
     unsigned long tem=0;    
          
	//调用涂鸦api同步时间,通过通讯接口获得了当前确切的绝对日期后再启动rtc模块自动更新时间功能
	if(!urtc_time1.initedFlg)
	{
		Urtc_SynTim();
		return;
	}
 
       ur
  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是使用C语言编写单片机RTC配置的示例代码,假设使用的是STM32F103单片机: ```c #include "stm32f10x.h" // 包含 STM32F103 系列芯片的头文件 // 定义 RTC 配置函数 void RTC_Configuration(void) { // 使能PWR和BKP外设时钟 RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE); // 启用备份区域 PWR_BackupAccessCmd(ENABLE); // 检查是否第一次配置RTC if (BKP_ReadBackupRegister(BKP_DR1) != 0x1234) { // 设置RTC时钟源 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_SetPrescaler(32767); // 为LSE时钟源设置RTC分频器,使得每秒钟RTC时钟为32768个计数值。因为 LSE 的频率为32.768kHz。 // 设置RTC初始时间 RTC_SetCounter(0); RTC_SetAlarm(10); RTC_WaitForLastTask(); // 将配置信息写入备份寄存器 BKP_WriteBackupRegister(BKP_DR1, 0x1234); } } ``` 该示例代码实现了以下功能: 1. 启用PWR和BKP外设时钟。 2. 启用备份区域。 3. 检查是否第一次配置RTC,若是,则进行RTC的初始化配置。 4. 设置RTC时钟源为LSE(外部低速振荡器)。 5. 等待LSE稳定,启用RTC时钟。 6. 设置RTC分频器,使得每秒钟RTC时钟为32768个计数值。 7. 设置RTC初始时间(这里设置为0秒),并设置一个闹钟(10秒后触发)。 8. 将配置信息写入备份寄存器。 需要注意的是,该示例代码中使用的是外部低速振荡器(LSE)作为RTC时钟源。如果使用其他时钟源,需要相应地修改代码。同时,需要根据实际需求修改RTC初始时间和闹钟触发时间。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值