1.DS1302是一种非常常见的RTC(实时时钟)芯片,TB网上卖的模块还不到5元,可以说是性价比很高了。如下图所示,共有5个引脚接口,除了电源外,还有CLK、DAT、RST三个引脚。
2.以下为RTC寄存器地址,依次为秒、分、小时、日、月、年、星期等,可以看出读的地址在写的基础上+1:
CLOCK BURST突发模式寄存器,一次读写所有时钟数据;RAM BURST突发模式寄存器,一次可以读写所有RAM数据:3.参考代码:
[EN] RTC DS1302 and Micropython - JarutEx
此代码用于ESP8266/ESP32,但K210情况有所不同,需要根据实际情况加以修改:
1)time改为utime(也可不改,不同固件略有差异)
2)K210不支持from machine import Pin,代之为GPIO设置,需from fpioa_manager import fm和from Maix import GPIO,使用方法CLK和RST为单向输出,DAT双向数据传输:
#引脚配置
CLK = 6
DAT = 7
RST = 8
fm.register(CLK, fm.fpioa.GPIO0)
fm.register(DAT, fm.fpioa.GPIO1)
fm.register(RST, fm.fpioa.GPIO2)
3)初始化__init__的参数要相应改为以下:
_sclk=GPIO.GPIO0, _io=GPIO.GPIO1, _ce=GPIO.GPIO2
4)为将时间显示到屏上,首先要import lcd,随后lcd.init(),使用lcd.draw_string方法。好处是无需字库,但缺点是不能调整字体大小。
4.以下是完整代码,dec2bcd和bcd2dec分别为十进制转BCD、BCD转十进制;read和write分别为读写DAT端口(此处命名为pinIO),受CLK时序控制,共进行8次;get和set分别为读写寄存器,受RST(此处命名为pinCE)时序控制;rtc.adjust设置时间,参数依次是日、月、年、星期第几天(星期日是第1天)、时、分、秒;rtc.now()获取当前时间;rtc.show()是将结果通过串口终端打印出来,同时显示在屏上:
from fpioa_manager import fm
from Maix import GPIO
import utime
import lcd
lcd.init()
#引脚配置
CLK = 6
DAT = 7
RST = 8
fm.register(CLK, fm.fpioa.GPIO0)
fm.register(DAT, fm.fpioa.GPIO1)
fm.register(RST, fm.fpioa.GPIO2)
# setting
class DS1302:
REG_SECOND = const(0x80)
REG_MINUTE = const(0x82)
REG_HOUR = const(0x84)
REG_DAY = const(0x86)
REG_MONTH = const(0x88)
REG_WEEKDAY= const(0x8A)
REG_YEAR = const(0x8C)
REG_WP = const(0x8E)
REG_CTRL = const(0x90)
REG_RAM = const(0xC0)
def __init__(self, _sclk=GPIO.GPIO0, _io=GPIO.GPIO1, _ce=GPIO.GPIO2):
self.pinClk =GPIO(_sclk, GPIO.OUT)
self.pinIO = GPIO(_io)
self.pinCE = GPIO(_ce, GPIO.OUT)
self.pinCE.value(0) # disable
self.pinClk.value(1)
self.rtc = [0,0,0,0,0,0,0] # y/m/d/dw/h/mi/s
def dec2bcd(self, n):
return ((n // 10 * 16) + (n % 10))
def bcd2dec(self, n):
return ((n // 16 * 10) + (n % 16))
def write(self, data):
self.pinIO.init( GPIO.OUT)
for i in range(8):
bit = (data & 0x01)
data = (data >> 1)
self.pinIO.value(bit)
self.pinClk.value(1)
self.pinClk.value(0)
def read(self):
self.pinIO.init( GPIO.IN)
byte = 0
for i in range(8):
bit = self.pinIO.value() & 0x01
bit = (bit << i)
byte = (byte | bit)
self.pinClk.value(1)
self.pinClk.value(0)
return byte
def set(self, reg, data):
self.pinCE.value(1)
self.pinCE.value(0) #
self.write( reg )
self.write( data )
self.pinCE.value(0)
def get(self, reg):
self.pinCE.value(1)
self.write( reg+1 )
data = self.read()
self.pinCE.value(0)
return data
def now(self):
self.rtc[0] = self.bcd2dec(self.get(REG_YEAR))+2000
self.rtc[1] = self.bcd2dec(self.get(REG_MONTH))
self.rtc[2] = self.bcd2dec(self.get(REG_DAY))
self.rtc[3] = self.bcd2dec(self.get(REG_WEEKDAY))
self.rtc[4] = self.bcd2dec(self.get(REG_HOUR))
self.rtc[5] = self.bcd2dec(self.get(REG_MINUTE))
self.rtc[6] = self.bcd2dec(self.get(REG_SECOND))
def adjust(self, day, month, year, dow, hour, minute, second ):
# convert
year = year - 2000
year = self.dec2bcd(year)
month = self.dec2bcd(month)
day = self.dec2bcd(day)
dow = self.dec2bcd(dow)
minute = self.dec2bcd(minute)
hour = hour & 0x1F
hour = self.dec2bcd(hour)
second = self.dec2bcd(second)
# adjust
self.set(REG_YEAR, year)
self.set(REG_MONTH, month)
self.set(REG_DAY, day)
self.set(REG_WEEKDAY, dow)
self.set(REG_HOUR, hour)
self.set(REG_MINUTE, minute)
self.set(REG_SECOND, second)
def show(self):
lcd.draw_string(60, 100, "{} {}-{}-{} {}:{}:{}".format(
self.rtc[3],
self.rtc[0], self.rtc[1], self.rtc[2],
self.rtc[4], self.rtc[5], self.rtc[6]
))
print("{} {}-{}-{} {}:{}:{}".format(
self.rtc[3],
self.rtc[0], self.rtc[1], self.rtc[2],
self.rtc[4], self.rtc[5], self.rtc[6]
))
# main program
rtc = DS1302()
#rtc.adjust(19,5,2022, 5, 12,57,00) #设置时间:日 月 年,星期第几天,时,分,秒
while True:
rtc.now()
rtc.show()
utime.sleep_ms(1000)
5.DS1302应该算是较早之前最为流行的RTC芯片,尤其是在51开发板上几乎是不二之选,目前由于对体积、功耗等要有要求,I2C总线的RTC芯片得以广泛应用,例如PCF8563。