RTC 实时时钟
大约 3 分钟ESP32Python
本节课来学习使用 MicroPython 中的 RTC 模块。
实验原理
RTC 全称为实时时钟(Real-time Clock),是一种与 CPU 互不干扰,独立于 CPU 运行的计时设备。
RTC 主要用于在计算机系统关机时,保存计算机系统时钟,以便在下次计算机系统开机时能够从 RTC 中恢复出正确的时间。
RTC 的应用场景非常广泛,例如实现时间戳功能、自动唤醒、计时器等。在一些需要记录时间的项目中,RTC 可以作为重要的时间标记。
硬件电路设计
物料清单(BOM 表):
材料名称 | 数量 |
---|---|
带有 IIC 模块的 LCD1602 液晶屏 | 1 |
杜邦线(跳线) | 若干 |
将材料按照下图相连:
注意
注意需要使用开发板上的 5V 电压,而不是 3.3V。真实环境下使用 3.3V 会无法显示或者显示很暗。
软件程序设计
MicroPython 集成了内置时钟模块,因此我们需要学习 RTC 的构造函数和使用方法:
构造函数 machine.RTC()
: 构建 RTC 对象。
使用方法如下:
import machine
# 创建 RTC 对象
rtc = machine.RTC()
# 设置日期与时间。按顺序分别是:(年,月,日,星期,时,分,秒,微秒)
# 其中星期使用 0-6 表示周一至周日
rtc.datetime(2023, 1, 1, 0, 0, 0, 0)
# 获取当前的时间
rtc.datetime()
我们可以使用 Thonny 给单片机同步实时时钟。
点击右下角,选择配置解释器。
勾选 同步设备的实时时钟
,点击确定,重新连接单片机即可。
注意
本实验需要用到 I2C 驱动代码,代码在 第 12 节课 中。
因此如果想要在 LCD 液晶屏上显示当前时间的话,可以这么写:
import time
from machine import Pin, RTC, SoftI2C
from libs.i2c_lcd import I2cLcd
# 定义一个 SoftI2C 的对象,指定 sda 和 scl 的 GPIO 口,并设置好通信的频率
i2c = SoftI2C(sda=Pin(14),scl=Pin(13),freq=100000)
# 获取 lcd 的地址,因为只控制了一个屏幕,因此选第 0 个设备的地址
DEFAULT_I2C_ADDR = i2c.scan()[0]
print(f"LCD设备为列表:{i2c.scan()}")
# 定义一个I2CLcd对象,设置模式为i2c,地址,行数,行的大小16个字节
lcd = I2cLcd(i2c, DEFAULT_I2C_ADDR, 2, 16)
# 定义 RTC 控制对象
rtc = RTC()
# 定义星期
week = ['Mon','Tue','Wed','Thu','Fri','Sat','Sun']
while True:
date_time=rtc.datetime()
lcd.clear()
lcd.putstr("%d-%02d-%02d %s\n" %(date_time[0],date_time[1],date_time[2], week[date_time[3]]))
lcd.putstr(" %02d:%02d:%02d" % (date_time[4],date_time[5],date_time[6]))
time.sleep(1)
我们也可以使用定时器来重写这段代码:
from machine import Pin, RTC, Timer, SoftI2C
from libs.i2c_lcd import I2cLcd
# 定义一个 SoftI2C 的对象,指定 sda 和 scl 的 GPIO 口,并设置好通信的频率
i2c = SoftI2C(sda=Pin(14),scl=Pin(13),freq=100000)
# 获取 lcd 的地址,因为只控制了一个屏幕,因此选第 0 个设备的地址
DEFAULT_I2C_ADDR = i2c.scan()[0]
print(f"LCD设备为列表:{i2c.scan()}")
# 定义一个I2CLcd对象,设置模式为i2c,地址,行数,行的大小16个字节
lcd = I2cLcd(i2c, DEFAULT_I2C_ADDR, 2, 16)
# 定义RTC控制对象
rtc=RTC()
# 定义定时器对象
timer = Timer(0)
# 定义星期
week=("Mon","Tue","Wed","Thu","Fri","Sat","Sun")
# 定义定时器中断函数
def timer_irq(timer_obj):
date_time=rtc.datetime()
print(date_time)
lcd.clear()
lcd.putstr("%d-%02d-%02d %s\n" %(date_time[0],date_time[1],date_time[2], week[date_time[3]]))
lcd.putstr(" %02d:%02d:%02d" % (date_time[4],date_time[5],date_time[6]))
# 初始化定时器对象
timer.init(mode=Timer.PERIODIC, period=1000, callback=timer_irq)