DS3231是一款高精度I2C实时时钟器件,具有集成的温度补偿晶体振荡器。该器件包含电池输入端,断开主电源时仍可保持精确计时。DS3231的寄存器能保存秒、分、时、星期、日期、月、年和闹钟设置等信息。少于31天的月份,可自动调整月末日期,包括闰年补偿。时钟的工作格式为24小时或带AM/PM指示的12小时格式。DS3231提供两个可编程日历闹钟和一路可编程方波输出。DS3231与单片机通过I2C双向串行总线传输地址与数据。
DS3231地址默认为:0x68 , 连接在esp32上的针脚为22和21
测试代码一 : 从DS3231读取时间,并将时间写入到ESP8266或ESP32设备中测试代码一 : 从DS3231读取时间,并将时间写入到ESP8266或ESP32设备中
import DS3231micro
import time
from machine import RTC
# 初始化DS3231时针芯片,注意设置针脚对应的数字:
Ds3231 = DS3231micro.DS3231(22, 21)
print("校时前:")
print(" 1、本地时间time.localtime(年月日时分秒、周几、本年第几天):", time.localtime())
print(" 2、DS3231时钟芯片的时间 (年月日、周几、时分秒) :",Ds3231.getDateTime())
print("\n")
time.sleep(1)
# 开始将DS3231的时间,写入本地设备中(格式为:年,月,日,周几,时,分,秒,毫秒):
rtc = RTC()
rtc.datetime(( Ds3231.getYear(), Ds3231.getMonth(), Ds3231.getDay(), Ds3231.getDayOfWeek(), Ds3231.getHour(), Ds3231.getMinutes(), Ds3231.getSeconds(), 0 ))
print("正在写入日期校时,顺序为:", Ds3231.getYear(), Ds3231.getMonth(), Ds3231.getDay(), Ds3231.getDayOfWeek(), Ds3231.getHour(), Ds3231.getMinutes(), Ds3231.getSeconds())
print("\n")
print("从DS3231校时后:")
print(" 1、本地时间time.localtime(年月日时分秒、周几、本年第几天): ", time.localtime())
print(" 1、本地时间rtc.datetime (年月日、周几、时分秒、亚秒): ", rtc.datetime())
print(" 2、DS3231时钟芯片的时间 (年月日、周几、时分秒): ",Ds3231.getDateTime())
测试代码二 : 从互联网NTP校时服务器获取时间,并写入DS3231中
测试代码二 : 从互联网NTP校时服务器获取时间,并写入DS3231中:
import time,ntptime #获取网络时间,校时使用
import network #导入network模块,以获取建立Wi-Fi网络连接所需的所有功能
import DS3231micro
# 先连接WIFI,注意一定要连接WIFI,否则无法从网络获取时间!
wlan = network.WLAN(network.STA_IF) # 以工作站 (wlan) 模式运行,需要创建一个工作站Wi-Fi接口的实例
wlan.active(True) # 在工作站对象上调用激活方法并以True作为输入值传递来激活网络接口
while not wlan.isconnected():
print("当前未联网,正在尝试连接到WIFI...." + str(time.time()))
wlan.connect("你的无线网SSID名称","你的无线网密码") # 无线网SSID、密码,开始联网
time.sleep(2)
if wlan.isconnected(): # 如果联接成功
IP_info=wlan.ifconfig()
print("\n无线网已经连接,信息如下:")
print(" IP地址:"+IP_info[0])
print(" 子网掩码:"+IP_info[1])
print(" 网关:"+IP_info[2])
print(" DNS:"+IP_info[3]+"\n")
# ESP8266或ESP32 【连接WIFI后,注意一定要连接WIFI】,从网络上的NTP服务器获取精准时间:
print("1、网络校时前本地时间:%s" %str(time.localtime()))
ntptime.NTP_DELTA = 3155644800 # 设置 UTC+8偏移时间(秒),不设置就是UTC0
ntptime.host = 'ntp1.aliyun.com' # 可选ntp服务器为阿里云服务器,默认是"pool.ntp.org"
ntptime.settime() # 修改设备时间,到这就已经设置好了
print("2、网络校时后本地时间:%s" %str(time.localtime()))
# 设置DS3231时钟芯片相关参数 设置针脚!
Ds3231 = DS3231micro.DS3231(22, 21)
print("3、目前DS3231时间:", Ds3231.getDateTime())
# 根据NTP的时间,对DS3231进行校时,顺序为:年、月、日、周几、时、分、秒, 如:Ds3231.setDateTime(2020, 10, 07, 2, 11, 22, 33)
Ds3231.setDateTime( time.localtime()[0],time.localtime()[1],time.localtime()[2], time.localtime()[6], time.localtime()[3],time.localtime()[4],time.localtime()[5] )
print("4、将从NTP网络校时服务器获取的时间写入DS3231后,DS3231时间为:", Ds3231.getDateTime())
测试代码三 : 设置和读取日期、时间
# DS3231 library for micropython
# tested on ESP8266
#
# Author: Sebastian Maerker
# License: mit
#
# only 24h mode is supported
#
# example on how to set the time on the DS3231
import DS3231micro
import machine
import time
# initialize DS3231 设置针脚!
Ds3231 = DS3231micro.DS3231(22, 21)
# set time to 2019, November, 23, Monday, 19 h, 50 min, 0 sec
Ds3231.setDateTime(19, 11, 23, 1, 19, 50, 0)
# print current time for 5 seconds
for each in range(5):
print(Ds3231.getDateTime())
print("\n")
time.sleep(1)
# set time with individual set functions
Ds3231.setYear(19)
Ds3231.setMonth(11)
Ds3231.setDay(23)
Ds3231.setDayOfWeek(1)
Ds3231.setHour(9)
Ds3231.setMinutes(33)
Ds3231.setSeconds(0)
# get hour, minutes, seconds for 5 seconds
for each in range(5):
print(Ds3231.getHour())
print(Ds3231.getMinutes())
print(Ds3231.getSeconds())
print("\n")
time.sleep(1)
测试代码四: 设置和读取闹钟
# DS3231 library for micropython
# tested on ESP8266
#
# Author: Sebastian Maerker
# License: mit
#
# only 24h mode is supported
#
# example on how to set and use the alarm on the DS3231
import DS3231micro
import machine
import time
#initialize DS3231
Dsc3231 = DS3231micro.DS3231(22, 21)
# set time to 2019, November, 23, Monday, 19 h, 50 min, 0 sec
Dsc3231.setDateTime(19, 11, 23, 1, 19, 50, 0)
# set alarm to go off every second
Dsc3231.setAlarm1(0, 22, 50, 10, "everySecond")
# turn on interrupt routine
Dsc3231.turnOnAlarmIR(1)
# PIN14 on controller becomes input pin to sense the IR pin
inputPinIR = machine.Pin(14, machine.Pin.IN)
# IR should be triggert every second for 5 seconds and is turned off afterwards
print("interrupt via pin")
for each in range(10):
if(inputPinIR.value() == False):
print("triggert")
Dsc3231.resetAlarmFlag(1)
time.sleep(0.5)
# IR should be tiggert every second for 5 seconds
print("interrupt via internal function")
for each in range(10):
if(Dsc3231.alarmTriggert(1)):
print("triggert")
time.sleep(0.5)
依赖的库文件,请将以下文件保存为 DS3231micro.py 并上传到esp32的lib文件夹中
# DS3231 library for micropython
# tested on ESP8266
#
# Author: Sebastian Maerker
# License: mit
#
# only 24h mode is supported
#
# features:
# - set time
# - read time
# - set alarms
import machine
from math import floor
i2cAddr = 0x68 # change I2C Address here if neccessary
class DS3231:
def __init__(self, i2cClockPin, i2cDataPin):
# create RTC instance with I2C Pins
self.sclPin = machine.Pin(i2cClockPin, pull = machine.Pin.PULL_UP, mode=machine.Pin.OPEN_DRAIN)
self.sdaPin = machine.Pin(i2cDataPin, pull = machine.Pin.PULL_UP, mode=machine.Pin.OPEN_DRAIN)
self.i2cVar = machine.I2C(-1, scl=self.sclPin, sda=self.sdaPin)
self.i2cAddr = i2cAddr
# get times functions -------------------------------------------------------------------------------------------------------
def getYear(self):
return decodeToDec(self.i2cVar.readfrom_mem(self.i2cAddr, 0x06, 1))
def getMonth(self):
temp = self.i2cVar.readfrom_mem(self.i2cAddr, 0x05, 1)
return decodeToDec(convertToByteType(temp[0] & 0x7F))
def getDay(self):
# 0 - 31
return decodeToDec(self.i2cVar.readfrom_mem(self.i2cAddr, 0x04, 1))
def getDayOfWeek(self):
# 1 - 7
return decodeToDec(self.i2cVar.readfrom_mem(self.i2cAddr, 0x03, 1))
def getHour(self):
temp = self.i2cVar.readfrom_mem(self.i2cAddr, 0x02, 1)
return decodeToDec(convertToByteType(temp[0] & 0x3F))
def getMinutes(self):
return decodeToDec(self.i2cVar.readfrom_mem(self.i2cAddr, 0x01, 1))
def getSeconds(self):
return decodeToDec(self.i2cVar.readfrom_mem(self.i2cAddr, 0x00, 1))
def getDateTime(self):
# returns whole date and time as list
# (last two digits of year, month, day, day of week, hour, minutes, seconds)
dateTime = [0, 0, 0, 0, 0, 0, 0]
dateTime[0] = self.getYear()
dateTime[1] = self.getMonth()
dateTime[2] = self.getDay()
dateTime[3] = self.getDayOfWeek()
dateTime[4] = self.getHour()
dateTime[5] = self.getMinutes()
dateTime[6] = self.getSeconds()
return dateTime
def getTemp(self):
#return decodeToDec(self.i2cVar.readfrom_mem(self.i2cAddr, 0x11, 2))
rev = self.i2cVar.readfrom_mem(self.i2cAddr,0x11, 2)
if rev[0] > 0x7F:
return rev[0] - rev[1] / 256 - 256
else:
return rev[0] - rev[1] / 256
# set times functions -------------------------------------------------------------------------------------------------------
def setYear(self, year):
# only last two digits (last two digits are used if longer)
if(year > 99):
thousands = floor(year / 100)
year = year - (thousands * 100)
self.i2cVar.writeto_mem(self.i2cAddr, 0x06, convertToByteType(encodeToByte(year)))
def setMonth(self, month):
self.i2cVar.writeto_mem(self.i2cAddr, 0x05, convertToByteType(encodeToByte(month) | 0))
def setDay(self, day):
# 0 - 31
self.i2cVar.writeto_mem(self.i2cAddr, 0x04, convertToByteType(encodeToByte(day)))
def setDayOfWeek(self, dayOfWeek):
# 1 - 7
self.i2cVar.writeto_mem(self.i2cAddr, 0x03, convertToByteType(encodeToByte(dayOfWeek)))
def setHour(self, hour):
self.i2cVar.writeto_mem(self.i2cAddr, 0x02, convertToByteType(encodeToByte(hour) & 0x3F))
def setMinutes(self, minutes):
self.i2cVar.writeto_mem(self.i2cAddr, 0x01, convertToByteType(encodeToByte(minutes)))
def setSeconds(self, seconds):
self.i2cVar.writeto_mem(self.i2cAddr, 0x00, convertToByteType(encodeToByte(seconds)))
def setDateTime(self, year, month, day, dayOfWeek, hour, minutes, seconds):
# set all the date and times (year is last two digits of year)
self.setYear(year)
self.setMonth(month)
self.setDay(day)
self.setDayOfWeek(dayOfWeek)
self.setHour(hour)
self.setMinutes(minutes)
self.setSeconds(seconds)
# get alarm functions ------------------------------------------------------------------------------------------------------
def getAlarm1(self):
# returns list as:
# dayOfWeek or day (depending on setup in setAlarm), hour, minutes, seconds, type of alarm
alarmTime = [0, 0, 0, 0, ""]
alarmTime[0] = self.i2cVar.readfrom_mem(self.i2cAddr, 0x0A, 1)[0]
alarmTime[1] = self.i2cVar.readfrom_mem(self.i2cAddr, 0x09, 1)[0]
alarmTime[2] = self.i2cVar.readfrom_mem(self.i2cAddr, 0x08, 1)[0]
alarmTime[3] = self.i2cVar.readfrom_mem(self.i2cAddr, 0x07, 1)[0]
alarmTime[4] = decodeAlarmType(alarmTime)
alarmTime = decodeAlarmTime(alarmTime)
return alarmTime
def getAlarm2(self):
# returns list as:
# dayOfWeek or day (depending on setup in setAlarm), hour, minutes, type of alarm
alarmTime = [0, 0, 0, ""]
alarmTime[0] = self.i2cVar.readfrom_mem(self.i2cAddr, 0x0D, 1)[0]
alarmTime[1] = self.i2cVar.readfrom_mem(self.i2cAddr, 0x0C, 1)[0]
alarmTime[2] = self.i2cVar.readfrom_mem(self.i2cAddr, 0x0B, 1)[0]
alarmTime[3] = decodeAlarmType(alarmTime)
alarmTime = decodeAlarmTime(alarmTime)
return alarmTime
def alarmTriggert(self, alarmNumber):
# check if alarm triggert and reset alarm flag
statusBits = self.i2cVar.readfrom_mem(self.i2cAddr, 0x0F, 1)[0]
if(statusBits & alarmNumber):
self.resetAlarm(alarmNumber)
return True
else:
return False
# set alarm functions -------------------------------------------------------------------------------------------------------
def setAlarm1(self, day, hour, minutes, seconds = 0, alarmType = "everyDay"):
# alarm Types are:
# "everySecond" - alarm every second
# "everyMinute" - alarm when seconds match
# "everyHour" - alarm when minutes and seconds match
# "everyDay" - alarm when hours, minutes and seconds match ! default !
# "everyWeek" - alarm when day of week, hours, minutes and seconds match
# "everyMonth" - alarm when day of month, hours, minutes and seconds match
alarmTime = encodeDateTime(day, hour, minutes, seconds, alarmType)
self.i2cVar.writeto_mem(self.i2cAddr, 0x07, convertToByteType(alarmTime[3]))
self.i2cVar.writeto_mem(self.i2cAddr, 0x08, convertToByteType(alarmTime[2]))
self.i2cVar.writeto_mem(self.i2cAddr, 0x09, convertToByteType(alarmTime[1]))
self.i2cVar.writeto_mem(self.i2cAddr, 0x0A, convertToByteType(alarmTime[0]))
def setAlarm2(self, day, hour, minutes, alarmType = "everyDay"):
# alarm Types are:
# "everyMinute" - alarm every minute (at 00 seconds)
# "everyHour" - alarm when minutes match
# "everyDay" - alarm when hours and minutes match ! default !
# "everyWeek" - alarm when day of week, hours and minutes match
# "everyMonth" - alarm when day of month, hours and minutes match
seconds = 0
alarmTime = encodeDateTime(day, hour, minutes, seconds, alarmType)
self.i2cVar.writeto_mem(self.i2cAddr, 0x0B, convertToByteType(alarmTime[2]))
self.i2cVar.writeto_mem(self.i2cAddr, 0x0C, convertToByteType(alarmTime[1]))
self.i2cVar.writeto_mem(self.i2cAddr, 0x0D, convertToByteType(alarmTime[0]))
def turnOnAlarmIR(self, alarmNumber):
# set alarm interrupt. AlarmNumber 1 or 2
# when turned on, interrupt pin on DS3231 is "False" when alarm has been triggert
controlRegister = self.i2cVar.readfrom_mem(self.i2cAddr, 0x0E, 1)[0]
setByte = 0x04
setByte = setByte + alarmNumber
setByte = controlRegister | setByte
self.i2cVar.writeto_mem(self.i2cAddr, 0x0E, convertToByteType(setByte))
def turnOffAlarmIR(self, alarmNumber):
# turn off alarm interrupt. Alarmnumber 1 or 2
# only initiation of interrupt is turned off,
# alarm flag is still set when alarm conditions meet (i don't get it either)
controlRegister = self.i2cVar.readfrom_mem(self.i2cAddr, 0x0E, 1)[0]
setByte = 0xFF
setByte = setByte - alarmNumber
setByte = controlRegister & setByte
self.i2cVar.writeto_mem(self.i2cAddr, 0x0E, convertToByteType(setByte))
def resetAlarmFlag(self, alarmNumber):
statusBits = self.i2cVar.readfrom_mem(self.i2cAddr, 0x0F, 1)[0]
self.i2cVar.writeto_mem(self.i2cAddr, 0x0F, convertToByteType(statusBits & (0xFF - alarmNumber)))
def convertToByteType(number):
return bytes([number])
def decodeToDec(byte):
return ((byte[0] >> 4) * 10) + (byte[0] & 0x0F)
def encodeToByte(dec):
tens = floor(dec / 10)
ones = dec - tens*10
return (tens << 4) + ones
def decodeAlarmType(alarmTime):
if(len(alarmTime) > 4):
m1Bit = (alarmTime[3] & 0x80) >> 7
else:
m1Bit = False
m2Bit = (alarmTime[2] & 0x80) >> 7
m3Bit = (alarmTime[1] & 0x80) >> 7
m4Bit = (alarmTime[0] & 0x80) >> 7
dayBit = (alarmTime[0] & 0x40) >> 6
if(m1Bit and m2Bit and m3Bit and m4Bit):
return "everySecond"
elif(not m1Bit and m2Bit and m3Bit and m4Bit):
return "everyMinute"
elif(not m1Bit and not m2Bit and m3Bit and m4Bit):
return "everyHour"
elif(not m1Bit and not m2Bit and not m3Bit and m4Bit):
return "everyDay"
elif(not dayBit and not m1Bit and not m2Bit and not m3Bit and not m4Bit):
return "everyMonth"
elif(dayBit and not m1Bit and not m2Bit and not m3Bit and not m4Bit):
return "everyWeek"
else:
return "noValidAlarmType"
def decodeAlarmTime(alarmTime):
alarmTime[0] = decodeToDec(convertToByteType(alarmTime[0] & 0x3F))
alarmTime[1] = decodeToDec(convertToByteType(alarmTime[1] & 0x3F))
alarmTime[2] = decodeToDec(convertToByteType(alarmTime[2] & 0x7F))
if(len(alarmTime) > 4):
alarmTime[3] = decodeToDec(convertToByteType(alarmTime[3] & 0x7F))
return alarmTime
def encodeAlarmType(alarmType):
if(alarmType == "everySecond"):
return 15 #0b01111
elif(alarmType == "everyMinute"):
return 14 #0b01110
elif(alarmType == "everyHour"):
return 12 #0b01100
elif(alarmType == "everyDay"):
return 8 #0b01000
elif(alarmType == "everyMonth"):
return 0 #0b00000
elif(alarmType == "everyWeek"):
return 16 #0b10000
else:
raise ValueError("""Not a supported alarmType. Options are:
'everySecond' (only Alarm 1), 'everyMinute', 'everyHour', 'everyDay', 'everyMonth', 'everyWeek'""")
def encodeDateTime(day, hour, minutes, seconds, alarmType):
alarmBits = encodeAlarmType(alarmType)
alarmTime = [0, 0, 0, 0]
alarmTime[0] = (encodeToByte(day) & 0x3F) | ((alarmBits & 0x10) << 2) | ((alarmBits & 0x08) << 4)
alarmTime[1] = (encodeToByte(hour) & 0x3F) | ((alarmBits & 0x04) << 5)
alarmTime[2] = (encodeToByte(minutes) & 0x7F) | ((alarmBits & 0x02) << 6)
alarmTime[3] = (encodeToByte(seconds) & 0x7F) | ((alarmBits & 0x01) << 7)
return alarmTime
网友评论