嵌入式人工智能(10-基于树莓派4B的DS1302实时时钟RTC)

news2024/9/22 21:33:02

1、实时时钟(Real Time Clock)

RTC,全称为实时时钟(Real Time Clock),是一种能够提供实时时间信息的电子设备。RTC通常包括一个计时器和一个能够记录日期和时间的电池。它可以独立于主控芯片工作,即使断电也能继续运行,并保持时间的精确度。

RTC一般用于需要准确时间的应用场合,如计算机系统的时间同步、数据采集系统的时间记录等。RTC可以提供秒、分、时、日、月、年等时间信息,还可以具备闹钟、定时器等功能。

在计算机系统中,RTC可以通过串行接口(如I2C、SPI接口)与主控芯片进行通信。主控芯片通过读取RTC的寄存器来获取当前时间,并可以通过写入寄存器来设置时间或功能。

除了计算机系统,RTC还可以用于其他电子设备中,如手机、电视等。

2、DS1302

(1)实时时钟芯片

DS1302是一款实时时钟芯片,由美国达拉斯半导体(Dallas Semiconductor)公司生产。它集成了时钟、日历和电池供电管理等功能。

DS1302通过3根线(数据线、时钟线和使能线)与外部控制器通信。它内部有一个32位的静态RAM,用于存储时间和日期等信息。它还有一个时钟输出引脚(CLKOUT),可以输出时钟信号。此外,DS1302还包括一个电池供电管理电路,可以在外部电源断开时维持时钟运行。

DS1302的主要特点如下:

  1. 时钟精度:±2分钟/月
  2. 工作电压:2V~5.5V
  3. 时钟频率:具有多个可选频率,最高可达到8MHz
  4. 时钟输出:可输出1Hz至32.768kHz的时钟信号
  5. 数据传输:采用串行方式传输,速率最高可达到2.048Mb/s
  6. 电源管理:具有电源失效检测和切换功能,可以自动切换到备用电池供电

DS1302广泛应用于各种需要实时时钟功能的设备,例如计算器、电子表、温度计、计步器、电子秤等。由于其低功耗和高精度的特点,它也常被用于嵌入式系统和物联网应用中。

(2)与树莓派接线

VCC:接树莓派的 3.3V 输出

GND:接树莓派的 Ground(地)

CLK:接树莓派的 GPIO21(BOARD 物理引脚编号40)

DAT:接树莓派的 GPIO20(BOARD 物理引脚编号38)

RST:接树莓派的 GPIO8(BOARD 物理引脚编号24)

(3)说明

DS1302的接线我特别说明下,我这里卡了一天,给我整懵了。我按照网上的接法接SLCK,ID_SD,CE0,运行程序老出问题,引脚功能报错,我估计接法不对,如果有同学整明白可以给我留言。我估计之前的接法是针对树莓派其他版本的。如果有时间还是要看下手册。

DS1302的接法还可以接到clk和IO引脚可以接树莓派SCL和SDA,不过不建议这样接,占用了OLED的引脚。如果接到这个IIC引脚上,通过sudo i2cdetect -y 1 命令也是查不到0x68这个1302器件ID。我这里也是搞了很长时间。

由于,DS1302的驱动在51和STM32都是通过IIC总线完成的,只要接到GPIO口,根据芯片手册的时序信号模拟IIC总线来发送与接收数据,主要有起始,结束、应答、非应答信号,再编写发送与接收字节函数,总之相比对程序员硬件软件要求比较高。在树莓派4B开发板中,DS1302也是基于IIC总线的,也有相应的C驱动和例程,但是我们还是用Pyhton来写。

3、DS1302驱动代码

import time
import RPi.GPIO
from datetime import datetime

# 使用物理编码
SCL = 40
IO = 38
RST = 24

# 数据读写的间隔
CLK_PERIOD = 0.00001

# 关闭GPIO警告
RPi.GPIO.setwarnings(False)
# 配置树莓派GPIO接口 使用物理编码
RPi.GPIO.setmode(RPi.GPIO.BOARD)

# 写入一个字节的数据
def writeByte(Byte):
    for Count in range(8):
        # 将SCL置为低电平 开启一次传输
        time.sleep(CLK_PERIOD)
        RPi.GPIO.output(SCL, 0)
        # 取一位数据进行写入
        Bit = Byte % 2
        Byte = int(Byte / 2)
        # 通过IO引脚进行写入
        time.sleep(CLK_PERIOD)
        RPi.GPIO.output(IO, Bit)
        # 将SCL置为高电平 结束一次传输
        time.sleep(CLK_PERIOD)
        RPi.GPIO.output(SCL, 1)

# 读取一个字节的数据
def readByte():
    # 将IO引脚设置为输入
    RPi.GPIO.setup(IO, RPi.GPIO.IN, pull_up_down=RPi.GPIO.PUD_DOWN)
    Byte = 0
    for Count in range(8):
        # 先将SCL重置为高电平
        time.sleep(CLK_PERIOD)
        RPi.GPIO.output(SCL, 1)
        # 将SCL置为低电平 开启一次传输
        time.sleep(CLK_PERIOD)
        RPi.GPIO.output(SCL, 0)
        # 读取一位数据
        time.sleep(CLK_PERIOD)
        Bit = RPi.GPIO.input(IO)
        Byte |= ((2 ** Count) * Bit)
    return Byte

# 重置一些数据
def resetDS1302():
    # SCL引脚设置为输出
    RPi.GPIO.setup(SCL, RPi.GPIO.OUT)
    # RST引脚设置为输出
    RPi.GPIO.setup(RST, RPi.GPIO.OUT)
    # IO引脚设置为输出
    RPi.GPIO.setup(IO, RPi.GPIO.OUT)
    # SCL和IO都置为低电平
    RPi.GPIO.output(SCL, 0)
    RPi.GPIO.output(IO, 0)
    time.sleep(CLK_PERIOD)
    # RST置为高电平
    RPi.GPIO.output(RST, 1)

# 结束操作
def endDS1302():
    # SCL引脚设置为输出
    RPi.GPIO.setup(SCL, RPi.GPIO.OUT)
    # RST引脚设置为输出
    RPi.GPIO.setup(RST, RPi.GPIO.OUT)
    # IO引脚设置为输出
    RPi.GPIO.setup(IO, RPi.GPIO.OUT)
    # SCL和IO都置为低电平
    RPi.GPIO.output(SCL, 0)
    RPi.GPIO.output(IO, 0)
    time.sleep(CLK_PERIOD)
    # RST置为低电平
    RPi.GPIO.output(RST, 0)


# 进行时间校准
def setDatetime(year, month, day,  hour, minute, second, dayOfWeek):
    # 引脚重置
    resetDS1302()
    # 设置写始终数据脉冲指令
    writeByte(int("10111110", 2))

    # 开始依次写数据
    # 写入秒数据,*16的作用是把十位右移4位 下面同
    writeByte((second % 10) | int(second / 10) * 16)
    # 写入分钟数据
    writeByte((minute % 10) | int(minute / 10) * 16)
    # 写入小时数据
    writeByte((hour % 10) | int(hour / 10) * 16)
    # 写入日期数据
    writeByte((day % 10) | int(day / 10) * 16)
    # 写入月份数据
    writeByte((month % 10) | int(month / 10) * 16)
    # 写入星期数据
    writeByte(dayOfWeek)
    # 写入年份数据
    writeByte((year % 100 % 10) | int(year % 100 / 10) * 16)
    # 结束数据写入
    writeByte(int("00000000", 2))
    # 结束任务
    endDS1302()

# 获取DS1302硬件时钟实践
def getDatetime():
    # 重置引脚
    resetDS1302()
    # 0xBF指令,开始时钟脉冲串读取数据
    writeByte(int("10111111", 2))

    Data = ""

    # 依次读取
    # 先读出秒数据
    Byte = readByte()
    second = (Byte % 16) + int(Byte / 16) * 10
    # 分钟数据
    Byte = readByte()
    minute = (Byte % 16) + int(Byte / 16) * 10
    # 小时数据
    Byte = readByte()
    hour = (Byte % 16) + int(Byte / 16) * 10
    # 日期数据
    Byte = readByte()
    day = (Byte % 16) + int(Byte / 16) * 10
    # 月份数据
    Byte = readByte()
    month = (Byte % 16) + int(Byte / 16) * 10
    # 星期数据
    Byte = readByte()
    day_of_week = (Byte % 16)
    # 年数据
    Byte = readByte()
    year = (Byte % 16) + int(Byte / 16) * 10 + 2000

    # 结束任务
    endDS1302()
    return datetime(year, month, day, hour, minute, second)

# 时间格式化
def format_time(dt):
    if dt is None:
        return ""
    fmt = "%m/%d/%Y %H:%M"
    return dt.strftime(fmt)

def parse_time(s):
    fmt = "%m/%d/%Y %H:%M"
    return datetime.strptime(s, fmt)

主要有2个函数,一个是setDatetime(year, month, day,  hour, minute, second, dayOfWeek),一个是getDatetime()。日期参数可以删掉,也可以随便给一个。在主程序中如果要引用这个驱动文件.py,使用 from ds1302 import * 。

4、主程序

from datetime import datetime

from ds1302 import *

import time





# 初始化程序

def datetime_setup():

	print ('')

	print ('')

	print (getDatetime())  # 获取时间信息

	print ('')

	print ('')

	ds_a = input( "Do you want to setup date and time?(y/n/c)\n c:Set the current time to the system time\n")     

	# 是否更新时间

	if ds_a == 'y' or ds_a == 'Y':                                           # 重新更新时间

		ds_date = input("Input date:(YYYY MM DD) ")                          # 输入年月日

		ds_time = input("Input time:(HH MM SS) ")                            # 输入时分秒

		ds_date = list(map(lambda x: int(x), ds_date.split()))                  # 判断格式        

		ds_time = list(map(lambda x: int(x), ds_time.split()))                  # 判断格式

		print ('')

		print ('')

		setDatetime(ds_date[0], ds_date[1], ds_date[2], ds_time[0], ds_time[1], ds_time[2],33) # 设置时间

		dt = getDatetime()             # 获取当前时间

		print ("You set the date and time to:", dt)  # 打印出当前时间

	if ds_a == 'c' or ds_a == 'C':    

		current_datetime()

		print ("current time is:", getDatetime()) 



# 循环函数

def datetime_loop():

	while True:

		dt= getDatetime()  # 获取时间

		print (dt)       # 打印出时间

		time.sleep(1) # 延时1S



# 释放资源

def resource_destory():

	endDS1302()				# 释放资源



#获取当前时间写入ds1302

def current_datetime():

	current = datetime.now()

	year = current.year

	month = current.month

	day = current.day

	hour = current.hour

	minute = current.minute

	second = current.second

	week = current.weekday()

	setDatetime(year,month,day,hour,minute,second,week)



# 程序入口

if __name__ == '__main__':		

	datetime_setup()

	try:

		datetime_loop()         # 循环函数

	except KeyboardInterrupt:  	# 当按下Ctrl+C时,将执行destroy()子程序。

		resource_destory()      # 释放资源

启动后可以不设置时间n,可以设置时间y,也可以读取系统时间设置到DS1302(C)。设置后,每隔一秒读取寄存器日期时间值,打印到屏幕上面。也可以显示到OLED上面。

显示到OLED上面需要把之前的显示封装成函数,在主程序中获取日期时间后调用。

5、问题

具体显示的结果参考之前的接线实物图,但是OLED显示会出现闪烁问题,就是用time.sleep(1)导致的,这个和C中的delay函数一样,对于这个问题,解决办法,是将获取时间函数直接放到OLED显示函数里面。

def Oled_display(x,y):
	global device
	device = load_device()
	font = ImageFont.truetype('STKAITI.TTF',16)
	while True:
		with canvas(device) as draw:
			draw.rectangle(device.bounding_box, outline=0, fill=0)
			draw.text((x,y),str(getDatetime()),font=font, fill='white')

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1939828.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

5.过滤器Filter(doFilter()+chain.doFilter())

过滤器Filter 文章目录 过滤器Filter一、过滤器简介1.定义2.作用3.拦截原理4.常用方法:5.Filter的生命周期4.web.xml中配置5.WebFilter 一、过滤器简介 1.定义 过滤器是对Web应用程序的请求和响应添加功能的Web服务组件(实现 javax.servlet.Filter 接口的 Java 类。) 调用web…

Neuralink首款产品Telepathy:意念控制设备的革新与挑战

近年来,科技领域不断涌现出令人惊叹的突破,其中尤以脑机接口(BCI)技术为代表。近日,Elon Musk的Neuralink公司发布了其首款脑机接口产品Telepathy,引发了广泛关注。本文将详细探讨Telepathy的功能、技术原理…

Java语言程序设计基础篇_编程练习题**15.6(两个消息交替出现)

**15.6(两个消息交替出现) 编写一个程序,当单击鼠标时面板上交替显示两个文本"Java is fun"和"Java is powerful" 代码展示:编程练习题15_6TwoInfo.java package chapter_15;import javafx.application.Application; import javafx…

JavaScript之Web APIs-DOM

目录 DOM获取元素一、Web API 基本认知1.1 变量声明1.2 作用和分类1.3 DOM树1.4 DOM对象 二、获取DOM对象2.1 通过CSS选择器来获取DOM元素2.2 通过其他方式来获取DOM元素 三、操作元素内容3.1 元素.innerTest属性3.2 元素.innerHTML属性 四、操作元素属性4.1 操作元素常用属性4…

mysql无法启动

总是报错: 1、Job for mysql.service failed because the control process exited with error code. See "systemctl status mysql.service" and "journalctl -xeu mysql.service" for details. 2、ERROR 2002 (HY000): Cant connect to local …

Linux可视化工具-netdata之docker安装

版本要求 docker cli安装 docker pull netdata/netdata docker run -d --namenetdata \ --pidhost \ --networkhost \ -v netdataconfig:/etc/netdata \ -v netdatalib:/var/lib/netdata \ -v netdatacache:/var/cache/netdata \ -v /:/host/root:ro,rslave \ -v /etc/passwd…

常用注意力机制 SENet CBAM ECA

在处理脑电信号时通常会用到一些注意力机制,来给不同的脑电通道不同的权重,进而体现出不同脑电通道在分类中的重要性。下面整理几种常见的通道注意力机制,方便以后查阅。 常用注意力机制 SENet CBAM ECA 注意力机制SENet(Squeeze-and-Excitation Network)SENet原理SENet P…

五. TensorRT API的基本使用-load-model

目录 前言0. 简述1. 案例运行2. 代码分析2.1 main.cpp2.2 model.hpp2.3 model.cpp2.4 其它 总结下载链接参考 前言 自动驾驶之心推出的 《CUDA与TensorRT部署实战课程》,链接。记录下个人学习笔记,仅供自己参考 本次课程我们来学习课程第五章—TensorRT …

达梦数据库审计日志采集

目录 1. 审计功能简介2. dm8官方技术参考文档3. dm8审计功能配置3.1 登录审计用户3.2 开启审计开关3.3 查询审计日志3.4 审计设置3.4.1 配置语句级审计3.4.2 取消语句级审计3.5 审计日志查阅4. python获取dm8审计日志1. 审计功能简介 审计机制是 DM 数据库管理系统安全管理的重…

第十一课:综合项目实践

下面是我们搭建的一个综合实践的拓扑图: 我们要完成以下目标: 网络中有3个不同部门,均可自动获取地址各部门可相互访问,也可访问内部服务网172.16.100.1,PC1不允许访问互联网,PC1和PC3可以访问互联网内网服…

nginx配置文件说明

Nginx的配置文件说明 Nginx配置文件的主要配置块可以分为三个部分:全局配置块(events和http块),events块和http块。这三个部分共同定义了Nginx服务器的整体行为和处理HTTP请求的方式。 全局配置块: 包含了影响Nginx服…

Vue3组件样式

在 Vue3开发中&#xff0c;我们经常需要对元素的类和样式进行动态控制。本文将详细介绍如何使用 Vue.js 的特性来实现这一目标。 class 绑定 绑定对象&#xff1a; 在 Vue.js 中&#xff0c;我们可以使用对象语法来绑定 class。例如&#xff1a; <div :class"{ act…

卸载顽固的驱动或软件

在Windows系统&#xff0c;有些软件或驱动&#xff0c;为了防止被卸载&#xff0c;特地在C:\Windows\System32\drivers目录里&#xff0c;生成xxx.sys文件。这些xxx.sys文件&#xff0c;无法直接删除&#xff0c;用杀毒软件也很难卸载。     这里介绍一种方法&#xff0c;可以…

基于GTX的64B66B编码的自定义接收模块(高速收发器二十二)

点击进入高速收发器系列文章导航界面 1、自定义PHY顶层模块 前文设计了64B66B自定义PHY的发送模块&#xff0c;本文完成自定义PHY剩余的模块的设计&#xff0c;整体设计框图如下所示。 其中phy_tx是自定义PHY的发送数据模块&#xff0c;scrambler是加扰模块&#xff0c;rx_slip…

阿里云OS Copilot:解锁操作系统运维与编程的智能助手

目录 引言 OS Copilot简介 OS Copilot的环境准备 创建实验资源 安全设置 设置安全组端口 创建阿里云AccessKey 准备系统环境 OS Copilot的实操 场景一、用OS Copilot写脚本和注释代码 场景二、使用OS Copilot进行对话问答 场景三、使用OS Copilot辅助编程学习 清理…

P15-P18-随机梯度下降-自适应学习率-超参数筛选-正则化

文章目录 随机梯度下降和自适应学习率超参数筛选交叉验证 正则化权重衰减Dropout 简介 本文主要讨论了机器学习中随机梯度下降&#xff08;SGD&#xff09;和自适应学习率算法的原理及应用。SGD通过随机选择小批量样本计算损失值&#xff0c;减少了计算量&#xff0c;加快了训练…

国内访问Docker Hub慢问题解决方法

在国内访问Docker Hub时可能会遇到一些困难&#xff0c;但幸运的是&#xff0c;有多种解决方案可以帮助你顺利下载Docker镜像。以下是一些有效的解决方案&#xff1a; 配置Docker镜像源&#xff1a;你可以通过配置Docker的daemon.json文件来使用国内镜像源&#xff0c;比如DaoC…

Spring Web MVC(一篇带你了解并入门,附带常用注解)

一&#xff0c;什么是Spring Web MVC 先看一下官网怎么说&#xff1a; 也就是Spring Web MVC一开始就是包含在Spring框架里面的&#xff0c;但通常叫做Spring MVC。 也可以总结出一个信息&#xff0c;这是一个Web框架。后面我就简称为Spring MVC了。 1.1MVC MVC也就是Mode…

202496读书笔记|《飞花令·菊(中国文化·古典诗词品鉴)》——荷尽已无擎雨盖,菊残犹有傲霜枝

202496读书笔记|《飞花令菊&#xff08;中国文化古典诗词品鉴&#xff09;》——荷尽已无擎雨盖&#xff0c;菊残犹有傲霜枝 《飞花令菊&#xff08;中国文化古典诗词品鉴&#xff09;》素心落雪 编著。飞花令得名于唐代诗人韩翃《寒食》中的名句“春城无处不飞花”&#xff0c…

食南之徒~马伯庸

◆ 第一章 >> 老赵&#xff0c;这你就不懂了。过大于功&#xff0c;要受罚挨打&#xff0c;不合算&#xff1b;功大于过&#xff0c;下回上司有什么脏活累活&#xff0c;第一时间会想到你&#xff0c;也是麻烦多多。只有功过相抵&#xff0c;上司既挑不出你的错&#xf…