第十八章 RTC实验 本章,我们将介绍如何使用ESP32-S3的系统时间,实现一个简单的实时时钟。 本章分为如下几个小节: 18.1 RTC介绍 18.2 硬件设计 18.3 软件设计 18.4 下载验证
18.1 RTC介绍 RTC,Real]在ESP32-S3中,并没有像STM32芯片一样,具有RTC外设,但是存在一个系统时间,利用系统时间,也可以实现实时时钟的功能效果。 ESP32-S3使用两种硬件时钟源建立和保持系统时间。根据应用目的及对系统时间的精度要求,既可以仅使用其中一种时钟源,也可以同时使用两种时钟源。这两种硬件时钟源为RTC定时器和高分辨率定时器。默认情况下,是使用这两种定时器。 <span]在Arduino开发中,我们需要下载一个“ESP32Time”软件库,该库用于设置和读取ESP32-S3内部RTC时间,我们就是基于这个库进行开发RTC功能。这个库,可以在Arduino IDE中库管理搜索到,具体下载操作如下图所示。 图18.1.1 ESP32Time库下载过程 假如在线安装不成功,也可以尝试使用手动安装方法,跟16.1.2小节描述的步骤是一样的。“ESP32Time.zip”压缩包在“资料盘à6,软件资料à2,Arduino软件包”文件夹下,下载成功后,便可以在“C:\Users\用户名\ Documents\Arduino\libraries\”路径下找到该文件。 ESP32Time库提供有三个示例工程,如下图所示: <span] 图18.1.2]在ESP32Time库中,总的来说,分为三类函数:设置时间、获取日期时间、提取日期时间的某个数据(年/月/日/时/分/秒)。 要使用该库的函数,所以需要先定义ESP32Time对象实例,操作如下: <span]这样定义ESP32Time对象实例,只需要rtc通过setTime函数设置好时间,rtc1就会在它的基础上+8小时,而不需要rtc1自己设置时间。简单理解,该功能就是可以设置相对时间。 接下来介绍一下,ESP32Time库的函数,如下所示。 setTime(30, 24, 15, 17, 1, 2021); // 17th Jan 2021 15:24:30 setTime(1609459200); // 1st Jan 2021 00:00:00 setTimeStruct(time); // set with time struct getTime() // (String) 15:24:38 getDate() // (String) Sun, Jan 17 2021 getDate(true) // (String) Sunday, January 17 2021 getDateTime() // (String) Sun, Jan 17 2021 15:24:38 getDateTime(true) // (String) Sunday, January 17 2021 15:24:38 getTimeDate() // (String) 15:24:38 Sun, Jan 17 2021 getTimeDate(true) // (String) 15:24:38 Sunday, January 17 2021 getMicros() // (unsigned long) 723546 getMillis() // (unsigned long) 723 getEpoch() // (unsigned long) 1609459200 getLocalEpoch() // (unsigned long) 1609459200 getSecond() // (int) 38 (0-59) getMinute() // (int) 24 (0-59) getHour() // (int) 3 (0-12) getHour(true) // (int) 15 (0-23) getAmPm() // (String) PM getAmPm(true) // (String) pm getDay() // (int) 17 (1-31) getDayofWeek() // (int) 0 (0-6) getDayofYear() // (int) 16 (0-365) getMonth() // (int) 0 (0-11) getYear() // (int) 2021 getTime("%A, %B %d %Y %H:%M:%S") //(String)returns time with specified format 通过看前面注释的说明,我们也比较清楚函数的使用了。 <span]本例程主要用到setTime函数和getTimeStruct函数,使用方法如下: rtc.setTime(00, 51, 17, 1, 12, 2023); /* 2023年12月1日17:52:00 */ struct tm timeinfo = rtc.getTimeStruct(); 使用getTimeStruct函数,把时间信息存进timeinfo结构体。通过这个结构体就可以获取年、月、日、时、分、秒等信息,该结构体类型如下: <span]RTC为ESP32-S3的片上资源,因此并没有相应的连接原理图。 18.3 软件设计 18.3.1 程序流程图 下面看看本实验的程序流程图: 图18.3.1 程序流程图 18.3.2 程序解析 1. 12_rtc.ino代码ESP32Time库的函数已经满足了例程需求,所以没有另外写rtc.cpp和rtc.h,所以这里直接介绍12_rtc.ino文件。 <span]在12_rtc.ino里面编写如下代码: #include "uart.h" #include "xl9555.h" #include "spilcd.h" #include <ESP32Time.h> /* 需要安装ESP32Time库 */ ESP32Time rtc; uint8_t tbuf[100]; /* 存放RTC信息 */ /** * @brief 当程序开始执行时,将调用setup()函数,通常用来初始化变量、函数等 * @param 无 * @retval 无 */ void setup() { uart_init(0, 115200); /* 串口0初始化 */ xl9555_init(); /* IO扩展芯片初始化 */ lcd_init(); /* LCD初始化 */ rtc.setTime(00, 51, 17, 1, 12, 2023); /* 2023年12月1日17:52:00 */ lcd_show_string(30, 50, 200, 16, LCD_FONT_16, "ESP32-S3", RED); lcd_show_string(30, 70, 200, 16, LCD_FONT_16, "RTC TEST", RED); lcd_show_string(30, 90, 200, 16, LCD_FONT_16, "ATOM@ALIENTEK", RED); } /** * @brief 循环函数,通常放程序的主体或者需要不断刷新的语句 * @param 无 * @retval 无 */ void loop() { struct tm timeinfo = rtc.getTimeStruct(); /* 根据time.h头文件中tm结构体的定义进行调整显示 */ sprintf((char *)tbuf, "Time:%02d:%02d:%02d", timeinfo.tm_hour-1, timeinfo.tm_min, timeinfo.tm_sec); lcd_show_string(30, 130, 210, 16, LCD_FONT_16, (char *)tbuf, RED); sprintf((char *)tbuf, "Date:%04d-%02d-%02d", timeinfo.tm_year+1900, timeinfo.tm_mon+1, timeinfo.tm_mday); lcd_show_string(30, 150, 210, 16, LCD_FONT_16, (char *)tbuf, RED); sprintf((char *)tbuf, "Week:%d", timeinfo.tm_wday); lcd_show_string(30, 170, 210, 16, LCD_FONT_16, (char *)tbuf, RED); delay(1000); } 在setup函数中,调用uart_init函数完成串口初始化,调用xl9555_init函数完成XL9555初始化,调用lcd_init函数完成LCD初始化,然后调用rtc.setTime函数设置年月日时分秒信息,然后LCD显示实验信息。 在loop函数中,调用rtc.getTimeStruct函数实现时间信息的获取,通过sprintf函数组合成字符串,然后调用lcd_show_string函数进行显示,这个过程是间隔一秒进行。 18.4 下载验证 下载代码后,LCD显示RTC实验信息,然后间隔一秒更新时间信息。 ]图18.4.1 RTC实验测试图
|