美文网首页
Esp8266/Esp32+DS3231时针芯片(2020-10

Esp8266/Esp32+DS3231时针芯片(2020-10

作者: 我开心0536 | 来源:发表于2020-10-06 23:20 被阅读0次
image.png

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

以上代码复制自: https://github.com/notUnique/DS3231micro

相关文章

  • Esp8266/Esp32+DS3231时针芯片(2020-10

    DS3231是一款高精度I2C实时时钟器件,具有集成的温度补偿晶体振荡器。该器件包含电池输入端,断开主电源时仍可保...

  • esp8266 esp32 docker 开发环境搭建

    esp-build 中文介绍 乐鑫WiFi(蓝牙)芯片程序构建环境 支持芯片:ESP8266 (tested)ES...

  • 最新:esp32与esp8266的区别

    首先给大家普及一下,esp32和esp8266是控制芯片,是芯片、是芯片。因为它们广泛被用于wifi模块,所以很多...

  • 基于ESP8266的技术总结(2)

    第一章我们建立了对ESP8266芯片的了解,并且将micropython的固件成功烧写到了esp8266芯...

  • ESP8266系列开发教程(一)

    ESP8266简介 ESP8266是上海乐鑫信息科技设计的低功耗WiFi芯片,集成完整的TCP/IP协议栈和MCU...

  • micropython for esp8266

    esp8266的确是一款超值的芯片,不仅可以是一款WIFI的芯片,可以兼容arduino,还可以使用micropy...

  • nodemcu和inventor的智能插盘实例

    2017年因为毕业设计我接触到了esp8266这款芯片,由于近年物联网开发的火热,这款芯片也成了非常热门的选...

  • ESP8266学习笔记(一)

    这段时间一直在想着设计一个远程遥控开关,所以这个星期在研究esp8266这款芯片,接下来我要讲的内容也是跟这个芯片...

  • 12.12

    ESP8266芯片,st.scan查看热点链接,st.connect连接热点输入密码,array确定是否有符号,多...

  • NodeMcu驱动oled屏幕使用心得

    NodeMcu驱动oled屏幕使用心得 在这之前一直使用的rots的固件开发esp8266芯片,采用c语言,开发过...

网友评论

      本文标题:Esp8266/Esp32+DS3231时针芯片(2020-10

      本文链接:https://www.haomeiwen.com/subject/iyuxpktx.html