【Micropython】ESP8266驱动DS1307读写操作以及同步RTC
- 相关篇《【Micropython】ESP8266通过NTP同步本地RTC时间》
DS1307读取和设置时间代码
from machine import I2C, Pin
import time
led = Pin(2,Pin.OUT) #板载led
# configure the I2C bus
i2c = I2C(scl=Pin(5), sda=Pin(4), freq=400000)
# 写入时间到DS1307当中启用
# seconds = ((10
# minutes = ((30
# hours = ((0
# weekday = 2 % 7 + 1
# day = ((19
# month = ((4
# year = ((2023 - 2000)
# 写入时间到DS1307当中
# i2c.writeto_mem(0x68, 0x00, bytes([seconds, minutes, hours, weekday, day, month, year]))
while True:
# led.on()
# send command to read current time
i2c.writeto(0x68, bytes([0x00]))
# read current time from DS1307
data = i2c.readfrom(0x68, 7)
seconds = (data[0] & 0x0f) + ((data[0] & 0x70) >> 4) * 10
minutes = (data[1] & 0x0f) + ((data[1] & 0x70) >> 4) * 10
hours = (data[2] & 0x0f) + (((data[2] & 0x30) >> 4) % 2) * 10
weekday = data[3]
day = (data[4] & 0x0f) + ((data[4] & 0x30) >> 4) * 10
month = (data[5] & 0x0f) + ((data[5] & 0x10) >> 4) * 10
year = (data[6] & 0x0f) + ((data[6] & 0xf0) >> 4) * 10
print('20{:02}/{:02}/{:02} {:02}:{:02}:{:02}'.format(year, month, day, hours, minutes, seconds))
led.value(not led.value()) # 反转LED状态
time.sleep(1) # 休眠1秒
从网络获取时间设置到DS1307
import machine
import ntptime
import network
import utime
from machine import Pin
led = Pin(2,Pin.OUT) #板载led
rtc_addr = 0x68
rtc_data = bytearray(7)
# 启动 RTC
def start_rtc():
i2c.writeto(rtc_addr, b'\x00') # 发送“控制寄存器”地址指令
rtc_data[0] = i2c.readfrom(rtc_addr, 1)[0]
if rtc_data[0] & 0x80 == 0:
rtc_data[0] |= 0x80 # 设置“控制寄存器”的停止位
i2c.writeto(rtc_addr, b'\x00' + rtc_data)
# 停止 RTC
def stop_rtc():
i2c.writeto(rtc_addr, b'\x00') # 发送“控制寄存器”地址指令
rtc_data[0] = i2c.readfrom(rtc_addr, 1)[0]
if rtc_data[0] & 0x80 != 0:
rtc_data[0] &= 0x7F # 清除“控制寄存器”的停止位
i2c.writeto(rtc_addr, b'\x00' + rtc_data)
# 获取 RTC 时钟
def get_rtc_datetime():
i2c.writeto(rtc_addr, b'\x00')
rtc_data = bytearray(i2c.readfrom(rtc_addr, 7))
year = 2000 + int(rtc_data[6])
month = int(rtc_data[5] & 0x1F)
day = int(rtc_data[4] & 0x3F)
weekday = int(rtc_data[3])
hour = int(rtc_data[2] & 0x3F)
minute = int(rtc_data[1] & 0x7F)
second = int(rtc_data[0] & 0x7F)
return (year, month, day, weekday, hour, minute, second)
# 初始化 I2C
i2c = machine.I2C(scl=machine.Pin(5), sda=machine.Pin(4))
i2c.scan() # 检测设备是否在线
# 启动 RTC
start_rtc()
# 连接网络
sta_if = network.WLAN(network.STA_IF)
sta_if.active(True)
sta_if.connect('#######', '********')
while not sta_if.isconnected():
pass
# 获取网络时间(UTC 时间)
ntptime.settime()
# 设置 RTC 时钟 将设备本地时间写入 DS1307 RTC
utc_time = utime.mktime(utime.localtime())
local_timezone = 28800 # 本地时区为 GMT+8
tm = utime.localtime(utc_time + local_timezone)
year = tm[0] - 2000
month = tm[1]
day = tm[2]
weekday = tm[6] + 1
hour = tm[3]
minute = tm[4]
second = tm[5]
#写入时间到DS1307当中
i2c.writeto_mem(0x68, 0x00, bytes([second, minute, hour, weekday, day, month, year]))
# 获取 RTC 时钟
print(get_rtc_datetime())
# 停止 RTC
stop_rtc()
while True:
print(get_rtc_datetime())
led.value(not led.value()) # 反转LED状态
utime.sleep(1)