K210(SiPEED MaixBit)MicroPython使用参考(七、RTC模块DS1302驱动)

11 篇文章 8 订阅

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。

 

 

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SDAU2005

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值