21-ESP32-S3实时时钟(RTC)

ESP32-S3实时时钟(RTC)的使用

ESP32-S3是一款高性能的Wi-Fi和蓝牙集成的系统级芯片(SoC),它包含一个实时时钟(RTC)模块,可以在系统的其他部分关闭时继续运行,以节省电能。下面是如何使用ESP32-S3的RTC模块的一些基本步骤。

RTC模块的基本功能

ESP32-S3的RTC模块具有以下主要功能:

  • 时间和日期:RTC模块可以提供实时的时间和日期信息。
  • 闹钟:可以设置RTC模块在特定的时间和日期发出信号。
  • 定时器:RTC模块可以作为一个定时器,用于在特定的时间间隔后发出信号。
  • 低功耗模式:当ESP32-S3的其他部分关闭时,RTC模块可以继续运行,以节省电能。

常用API

1.设置当前时间 settimeofday函数

settimeofday函数用于设置系统时间。它的原型如下:

c 复制代码
int settimeofday(const struct timeval *tv, const struct timezone *tz);

其中,tv参数是一个指向timeval结构体的指针,该结构体包含了要设置的时间(以自Epoch(1970-01-01 00:00:00 +0000 (UTC))以来的秒数和微秒数)。tz参数在现代系统中通常被忽略,应设置为NULL。

如果函数执行成功,返回0;如果失败,返回-1,并设置errno以指示错误。

2.获取当前时间 localtime_r函数

localtime_r函数用于将time_t类型的时间(自Epoch以来的秒数)转换为本地时间表示的tm结构体。它的原型如下:

c 复制代码
struct tm *localtime_r(const time_t *timer, struct tm *buf);

其中,timer参数是一个指向time_t类型的指针,表示要转换的时间;buf参数是一个指向tm结构体的指针,用于存储转换后的时间。

localtime_r函数是线程安全的,因为它使用用户提供的存储空间来存储结果,而不是使用静态存储空间。如果函数执行成功,返回指向结果的指针;如果失败,返回NULL。

3.设置时间环境变量

setenv是一个用于设置环境变量的函数。它的原型如下:

c 复制代码
int setenv(const char *name, const char *value, int overwrite);

其中,name是要添加或修改的环境变量的名称,value是环境变量的新值,overwrite是一个标志,表示当环境变量name已经存在时是否覆盖其值。

  • 如果overwrite非零,那么无论环境变量name是否存在,都将其值设置为value
  • 如果overwrite为零,那么只有当环境变量name不存在时,才将其值设置为value

setenv函数返回0表示成功,返回-1表示失败。

例如,setenv("TZ", "CST-8", 1);这行代码的作用是设置环境变量TZ的值为CST-8,表示中国标准时间,即UTC+8。这样,当你获取或设置RTC模块的时间时,它就会按照中国标准时间来进行。

关于 协调时间时 的概念

UTC(Coodinated Universal Time),又称协调世界时,世界统一时间、世界标准时间、国际协调时间。由于英文(CUT)和法文(TUC)的缩写不同,作为妥协,简称UTC。

UTC是现在全球通用的时间标准,全球各地都同意将各自的时间进行同步协调。UTC是以原子时秒长为基础,在时刻上尽量接近于世界时的一种时间计量系统。

UTC基于国际原子时,并通过不规则的加入闰秒来抵消地球自转变慢的影响。闰秒在必要的时候会被插入到UTC中,以保证协调世界时(UTC)与世界时(UT1)相差不超过0.9秒。

如何设置RTC模块

写一个示例,设置当前时间然后获取当前时间 打在串口上

c 复制代码
#include <time.h>  // 引入时间库

void setup() {
  // 初始化串口
  Serial.begin(115200);  // 设置串口波特率为115200

  // 设置当前时间
  struct tm timeinfo;  // 定义一个tm结构体变量timeinfo
  timeinfo.tm_year = 2024 - 1900;  // 设置年份
  timeinfo.tm_mon = 5 - 1;  // 设置月份
  timeinfo.tm_mday = 2;  // 设置日期
  timeinfo.tm_hour = 13;  // 设置小时
  timeinfo.tm_min = 45;  // 设置分钟
  timeinfo.tm_sec = 30;  // 设置秒
  setenv("TZ", "CST-8", 1);  // 设置时区为中国标准时间
  tzset();  // 使时区设置生效
  const time_t now = mktime(&timeinfo);  // 将tm结构体转换为time_t格式
  struct timeval tv = { .tv_sec = now };  // 定义一个timeval结构体变量tv,并设置其秒数
  settimeofday(&tv, NULL);  // 设置系统时间

  // 获取并打印当前时间
  time_t now_get;  // 定义一个time_t变量now_get
  struct tm timeinfo_get;  // 定义一个tm结构体变量timeinfo_get
  time(&now_get);  // 获取当前时间
  localtime_r(&now_get, &timeinfo_get);  // 将time_t格式的时间转换为tm结构体格式
  Serial.print("Current time: ");  // 打印字符串"Current time: "
  Serial.print(timeinfo_get.tm_hour);  // 打印小时
  Serial.print(":");  // 打印冒号
  Serial.print(timeinfo_get.tm_min);  // 打印分钟
  Serial.print(":");  // 打印冒号
  Serial.println(timeinfo_get.tm_sec);  // 打印秒数并换行
}

void loop() {
  // 延时1秒
  delay(1000);  // 暂停1秒
}

这个示例首先在setup()函数中设置了当前时间为2024年5月2日13:45:30,然后立即获取并打印当前时间。这样,你就可以在串口监视器上看到设置的当前时间了。

🚨注意setenv("TZ", "CST-8", 1); 这行代码的作用是设置时区为中国标准时间。,setenv函数用于设置环境变量。这里,设置了TZ环境变量的值为CST-8,表示中国标准时间,即UTC+8。这样,当你获取或设置RTC模块的时间时,它就会按照中国标准时间来进行。如果你想设置为其他时区,只需将CST-8替换为相应的时区即可。例如,如果你想设置为美国东部标准时间,可以将CST-8替换为EST5EDT

🚨注意在C语言的tm结构体中,tm_year字段表示的是自1900年以来的年数,tm_mon字段表示的是月份,但是它的范围是0(一月)到11(十二月)。所以,当我们设置tm_yeartm_mon字段的值时,需要进行相应的调整:

  • 对于年份,我们需要从实际年份中减去1900。例如,我们想要设置年份为2024,那么tm_year应该设置为2024 - 1900

  • 对于月份,我们需要从实际月份中减去1。例如,如果我们想要设置月份为5月,那么tm_mon应该设置为5 - 1

这样,2024 - 19005 - 1就分别表示了年份2024和5月。

总结

参考资料

ESP-IDF 系统时间

微软copilot

相关推荐
智商偏低3 小时前
单片机之helloworld
单片机·嵌入式硬件
青牛科技-Allen4 小时前
GC3910S:一款高性能双通道直流电机驱动芯片
stm32·单片机·嵌入式硬件·机器人·医疗器械·水泵、
森焱森6 小时前
无人机三轴稳定控制(2)____根据目标俯仰角,实现俯仰稳定化控制,计算出升降舵输出
c语言·单片机·算法·架构·无人机
白鱼不小白6 小时前
stm32 USART串口协议与外设(程序)——江协教程踩坑经验分享
stm32·单片机·嵌入式硬件
S,D7 小时前
MCU引脚的漏电流、灌电流、拉电流区别是什么
驱动开发·stm32·单片机·嵌入式硬件·mcu·物联网·硬件工程
芯岭技术10 小时前
PY32F002A单片机 低成本控制器解决方案,提供多种封装
单片机·嵌入式硬件
youmdt10 小时前
Arduino IDE ESP8266连接0.96寸SSD1306 IIC单色屏显示北京时间
单片机·嵌入式硬件
嘿·嘘10 小时前
第七章 STM32内部FLASH读写
stm32·单片机·嵌入式硬件
Meraki.Zhang11 小时前
【STM32实践篇】:I2C驱动编写
stm32·单片机·iic·驱动·i2c
几个几个n13 小时前
STM32-第二节-GPIO输入(按键,传感器)
单片机·嵌入式硬件