物联网开发笔记(99)- Micropython ESP32 C3开发之DS1302时钟模块并用st7789屏幕显示时间
一、目的
这一节我们学习如何使用合宙的ESP32 C3开发板开发DS1302T时钟模块(模块带电池),然后通过1.3寸彩色TFT显示屏模块(分辨率240*240,SPI接口,ST7789驱动芯片)来显示。
二、环境
ESP32 C3(MicroPython v1.19.1 on 2022-06-18) + Thonny(V4.0.1) + 1.3寸 ST7789 显示屏模块 +DS1302时钟模块 + 几根杜邦线 + Win10 商业版
st7789屏幕接线方法,st7789屏幕驱动和字体请参考下文:
物联网开发笔记(89)- 使用Micropython开发ESP32开发板之合宙ESP32 C3开发板通过串口SPI控制st7789 TFT液晶屏1.3寸_魔都飘雪的博客-CSDN博客使用Micropython开发ESP32开发板之合宙ESP32 C3开发板通过串口SPI控制st7789 TFT 1.3寸液晶屏https://blog.csdn.net/zhusongziye/article/details/129347036?spm=1001.2014.3001.5501
DS1302T时钟模块接线方法:
三、DS1302T时钟模块驱动
from machine import Pin
DS1302_REG_SECOND = (0x80)
DS1302_REG_MINUTE = (0x82)
DS1302_REG_HOUR = (0x84)
DS1302_REG_DAY = (0x86)
DS1302_REG_MONTH = (0x88)
DS1302_REG_WEEKDAY= (0x8A)
DS1302_REG_YEAR = (0x8C)
DS1302_REG_WP = (0x8E)
DS1302_REG_CTRL = (0x90)
DS1302_REG_RAM = (0xC0)
class DS1302:
def __init__(self, clk, dio, cs):
self.clk = clk
self.dio = dio
self.cs = cs
self.clk.init(Pin.OUT)
self.cs.init(Pin.OUT)
def _dec2hex(self, dat):
return (dat//10) * 16 + (dat % 10)
def _hex2dec(self, dat):
return (dat//16) * 10 + (dat % 16)
def _write_byte(self, dat):
self.dio.init(Pin.OUT)
for i in range(8):
self.dio.value((dat >> i) & 1)
self.clk.value(1)
self.clk.value(0)
def _read_byte(self):
d = 0
self.dio.init(Pin.IN)
for i in range(8):
d = d | (self.dio.value() << i)
self.clk.value(1)
self.clk.value(0)
return d
def _get_reg(self, reg):
self.cs.value(1)
self._write_byte(reg)
t = self._read_byte()
self.cs.value(0)
return t
def _set_reg(self, reg, dat):
self.cs.value(1)
self._write_byte(reg)
self._write_byte(dat)
self.cs.value(0)
def _wr(self, reg, dat):
self._set_reg(DS1302_REG_WP, 0)
self._set_reg(reg, dat)
self._set_reg(DS1302_REG_WP, 0x80)
#开启
def start(self):
t = self._get_reg(DS1302_REG_SECOND + 1)
self._wr(DS1302_REG_SECOND, t & 0x7f)
#关闭
def stop(self):
t = self._get_reg(DS1302_REG_SECOND + 1)
self._wr(DS1302_REG_SECOND, t | 0x80)
#秒
def second(self, second=None):
if second == None:
return self._hex2dec(self._get_reg(DS1302_REG_SECOND+1)) % 60
else:
self._wr(DS1302_REG_SECOND, self._dec2hex(second % 60))
#分
def minute(self, minute=None):
if minute == None:
return self._hex2dec(self._get_reg(DS1302_REG_MINUTE+1))
else:
self._wr(DS1302_REG_MINUTE, self._dec2hex(minute % 60))
#时
def hour(self, hour=None):
if hour == None:
return self._hex2dec(self._get_reg(DS1302_REG_HOUR+1))
else:
self._wr(DS1302_REG_HOUR, self._dec2hex(hour % 24))
#工作日
def weekday(self, weekday=None):
if weekday == None:
return self._hex2dec(self._get_reg(DS1302_REG_WEEKDAY+1))
else:
self._wr(DS1302_REG_WEEKDAY, self._dec2hex(weekday % 8))
#天
def day(self, day=None):
if day == None:
return self._hex2dec(self._get_reg(DS1302_REG_DAY+1))
else:
self._wr(DS1302_REG_DAY, self._dec2hex(day % 32))
#月
def month(self, month=None):
if month == None:
return self._hex2dec(self._get_reg(DS1302_REG_MONTH+1))
else:
self._wr(DS1302_REG_MONTH, self._dec2hex(month % 13))
#年
def year(self, year=None):
if year == None:
return self._hex2dec(self._get_reg(DS1302_REG_YEAR+1)) + 2000
else:
self._wr(DS1302_REG_YEAR, self._dec2hex(year % 100))
#获取或设置时间
def date_time(self, dat=None):
if dat == None:
return [self.year(), self.month(), self.day(), self.weekday(), self.hour(), self.minute(), self.second()]
else:
self.year(dat[0])
self.month(dat[1])
self.day(dat[2])
self.weekday(dat[3])
self.hour(dat[4])
self.minute(dat[5])
self.second(dat[6])
#返回设置结果
def ram(self, reg, dat=None):
if dat == None:
return self._get_reg(DS1302_REG_RAM + 1 + (reg % 31)*2)
else:
self._wr(DS1302_REG_RAM + (reg % 31)*2, dat)
四、示例代码1
DS1302_clock.py
from machine import Pin,SPI
from st7789py import ST7789,color565
from ds1302 import DS1302
import vga2_8x16 as font8x16
import vga2_bold_16x32 as font16x32
import time
# 创建SPI对象
spi = SPI(1,baudrate = 60_000_000,polarity = 1,sck = Pin(2),mosi = Pin(3),miso = None)
# 创建屏幕对象
tft = ST7789(spi,240,240,reset=Pin(10,Pin.OUT), dc=Pin(6,Pin.OUT),cs = None,backlight=Pin(8),rotation=180)
# 创建DS1302时钟对象
ds = DS1302(clk = Pin(12), dio = Pin(18), cs = Pin(19))
# 定义时钟函数
def Time():
# 定义一个星期列表
week = ['Mon','Tues','Wednes','Thurs','Fri','Satur','Sun']
#年,月,日,星期,时,分,秒
if ds.date_time()[0] != 2023:
# 设置DS1302时间
ds.date_time((2023,3,24,4,21,28,20))
tft.text(font8x16,"Initialization time ",20,0,color565(255,0,0),color565(0,0,0))
time.sleep(1)
tft.text(font8x16,"Initialization completed",20,0,color565(0,255,0),color565(0,0,0))
# year, month, mday, weekday, hour, minute, second
date = ds.date_time()
year = date[0]
month = date[1]
mday = date[2]
weekday = date[3]
hour = date[4]
minute = date[5]
second = date[6]
tft.text(font8x16,"%d-%.2d-%.2d %.2d:%.2d:%.2d [%s]" % (year,month,mday,hour,minute,second,week[weekday]),14,60,color565(0,255,0),color565(0,0,0))
tft.text(font16x32,"%.2d:%.2d:%.2d"%(hour,minute,second),50,108,color565(255,255,0),color565(0,0,0))
def main():
while True:
Time()
if __name__ == "__main__":
main()
显示效果:
五、上电自动运行
我们把代码写在main.py中,代码则可以上电后自动运行。
from DS1302_clock import Time
def main():
while True:
Time()
if __name__ == "__main__":
main()
六、DS1302 实时时钟模块购买
https://item.taobao.com/item.htm?spm=a1z09.2.0.0.6ea92e8dsqtsNJ&id=609527215102&_u=op01rch5634https://item.taobao.com/item.htm?spm=a1z09.2.0.0.6ea92e8dsqtsNJ&id=609527215102&_u=op01rch5634
DS1302实时时钟模块
DS1302 是DALLAS 公司推出的涓流充电时钟芯片,内含有一个实时时钟/日历和31 字节静态RAM ,通过简单的串行接口与单片机进行通信。实时时钟/日历电路提供秒、分、时、日、周、月、年的信息,每月的天数和闰年的天数可自动调整。时钟操作可通过AM/PM 指示决定采用24 或12 小时格式。DS1302 与单片机之间能简单地采用同步串行的方式进行通信,仅需用到三个口线:(1)RST 复位(2)I/O 数据线(3)SCLK串行时钟。时钟/RAM 的读/写数据以一个字节或多达31 个字节的字符组方式通信。DS1302 工作时功耗很低保持数据和时钟信息时功率小于1mW
DS1302主要性能指标:
★ 实时时钟具有能计算2100 年之前的秒、分、时、日、星期、月、年的能力,还有闰年调整的能力
★ 31 8 位暂存数据存储RAM
★ 串行 I/O 口方式使得管脚数量最少
★ 宽范围工作电压2.0 5.5V
★ 工作电流 2.0V 时,小于300nA
★ 读/写时钟或RAM 数据时有两种传送方式单字节传送和多字节传送字符组方式
★ 8 脚DIP 封装或可选的8 脚SOIC 封装根据表面装配
★ 简单 3 线接口
★ 与 TTL 兼容Vcc=5V
★ 可选工业级温度范围-40 +85
★ 双电源管用于主电源和备份电源供应
DS1302实时时钟模块参数如下:
1.PCB为单面板,尺寸:44mm*23mm*1.6mm
2.带4个定位孔,直径3.1mm
3.备用电池为正品天球CR2032,电压3V,电流260mAh,非可充电电池。理论数据保持时间大于10年!
4.晶振32.768KHz,日本原装进口晶振,匹配电容为6pF,尺寸2*6mm
5.DS1302为8脚直插国产大芯片,芯片下面有IC座,方便更换及插拔芯片
6.模块工作电压兼容3.3V/5V,可与5V及3.3V单片机连接
7.工作温度:0°---70°
接线方法(以提供的程序为例,可以接任意IO口,在程序中修改端口定义即可):
VCC→+5V/3.3V
GND→GND
CLK→P02
DAT→P01
RST→P00
注意事项:
1. VCC与GND千万不要接反,以免烧坏芯片
2. 51单片机P0口需要接上拉电阻,如果您的单片机没有接上拉电阻,可以将数据线接到其它端口
Bonjir: 写的真好啊网上关于micropython挂载sd卡的文章很少,你这篇直接把esp32cam讲透了 另外要说一点,那个oserror:camera init失败的问题,不用deinit,只需reset一下,然后在每次capture之后sleep个0.5s就可以了
jyh1103: 我发现几乎所有关于【thonny自带库模块安装到设备】都漏了一个大问题: 即 thonny自带库模块无法 import(如 ImportError: no module named 'websockets'。诸如 Lib 下的 asyncio、logging、site-packages 等也都不行)。 实际上,自己编的库.py 一般放到设备的 /common 下、下载的常用库(如 microdot-main)一般放到设备的 /lib 下。 回到主题,那 thonny自带库模块,怎么【挑出来(否则太多太大)】放到设备 ?
人生心電圖: 点击运行为什么没有反应
2301_77221418: 作者讲的流程很清晰易懂
??462: 显示不是很流畅咋办