当前位置: 首页 > news >正文

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

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 % 2Byte = 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 = 0for 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 datetimefrom 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()				# 释放资源#获取当前时间写入ds1302def current_datetime():current = datetime.now()year = current.yearmonth = current.monthday = current.dayhour = current.hourminute = current.minutesecond = current.secondweek = 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 devicedevice = 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')

相关文章:

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

1、实时时钟(Real Time Clock) RTC,全称为实时时钟(Real Time Clock),是一种能够提供实时时间信息的电子设备。RTC通常包括一个计时器和一个能够记录日期和时间的电池。它可以独立于主控芯片工作&#xff…...

C++ | Leetcode C++题解之第275题H指数II

题目&#xff1a; 题解&#xff1a; class Solution { public:int hIndex(vector<int>& citations) {int n citations.size();int left 0, right n - 1;while (left < right) {int mid left (right - left) / 2;if (citations[mid] > n - mid) {right m…...

编写DockerFile

将自己的项目或者环境通过Docker部署到服务器需要一下几个步骤&#xff1a; 打包项目或者环境 编写Dockerfile文件 运行Dockerfile文件&#xff0c;构建DockerImages镜像&#xff0c;将DockerImages存入DockerHub或者存入阿里云镜像仓库 服务器pull下DockerImages镜像&#…...

TCP并发服务器多线程

1.创建线程‐‐pthread_create int pthread_create( pthread_t *thread, // 线程 ID 无符号长整型 const pthread_attr_t *attr, // 线程属性&#xff0c; NULL void *(*start_routine)(void *), // 线程处理函数 void *arg); // 线程处理函数 参数&#xff1a; pthrea…...

技术速递|C# 13:探索最新的预览功能

作者&#xff1a;Kathleen Dollard 排版&#xff1a;Alan Wang C# 13 已初具雏形&#xff0c;其新特性侧重于灵活性、性能以及使您最喜欢的功能在日常中变得更容易使用。我们以公开的方式构建 C#&#xff0c;在今年的 Microsoft Build 大会上&#xff0c;我们会让您一睹 C# 13 …...

Python设计模式:巧用元类创建单例模式!

✨ 内容&#xff1a; 今天我们来探讨一个高级且实用的Python概念——元类&#xff08;Metaclasses&#xff09;。元类是创建类的类&#xff0c;它们可以用来控制类的行为。通过本次练习&#xff0c;我们将学习如何使用元类来实现单例模式&#xff0c;确保某个类在整个程序中只…...

构建自主可控的工业操作系统,筑牢我国工业安全堡垒

构建自主可控的工业操作系统&#xff0c;筑牢我国工业安全堡垒&#xff0c;鸿道(Intewell)操作系统为国家工业发展保驾护航。 7月19日&#xff0c;全球多地安装微软操作系统的电脑设备出现大规模宕机&#xff0c;导致“蓝屏”现象&#xff0c;严重影响了航空、铁路、医疗、金…...

WPF串口通讯程序

目录 一 设计原型 二 后台源码 一 设计原型 二 后台源码 using HardwareCommunications; using System.IO.Ports; using System.Windows;namespace PortTest {/// <summary>/// Interaction logic for MainWindow.xaml/// </summary>public partial class MainW…...

汽车技术智能化程度不断提升,线束可靠性如何设计?

随着汽车技术的高速发展&#xff0c;汽车自动化、智能化程度的逐步提高&#xff0c;人们对汽车的安全性、舒适性、娱乐性等要求也不断提高&#xff0c;加上汽车节能减排法规的不断严峻&#xff0c;整车电气设备不断增加&#xff0c;作为连接汽车各种电器设备“神经网络”的整车…...

实现Nginx的反向代理和负载均衡

一、反向代理和负载均衡简介 1.1、反向代理 反向代理(reverse proxy)指:以代理服务器来接受Internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给Internet上请求连接的客户端。此时代理服务器对外就表现为一个反向代理服务器。 反向代…...

【算法】子集

难度&#xff1a;中等 题目&#xff1a; 给你一个整数数组 nums &#xff0c;数组中的元素 互不相同 。返回该数组所有可能的 子集&#xff08;幂集&#xff09;。 解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。 示例 1&#xff1a; 输入&#xff1a;nums [1,…...

Web前端:HTML篇(一)

HTML简介&#xff1a; 超文本标记语言&#xff08;英语&#xff1a;HyperText Markup Language&#xff0c;简称&#xff1a;HTML&#xff09;是一种用于创建网页的标准标记语言。 您可以使用 HTML 来建立自己的 WEB 站点&#xff0c;HTML 运行在浏览器上&#xff0c;由浏览器…...

ActiViz中的选择点vtkWorldPointPicker

文章目录 1. vtkWorldPointPicker简介2. 类的位置和继承关系3. 选择机制4. 返回的信息5. 选择的条件和参数6. 与屏幕空间选择器的比较7. 性能特征8. 应用场景9. 与其他vtk选择器的集成10. 完整示例总结1. vtkWorldPointPicker简介 vtkWorldPointPicker是Visualization Toolkit…...

如何开启或者关闭 Windows 安全登录?

什么是安全登录 什么是 Windows 安全登录呢&#xff1f;安全登录是 Windows 附加的一个组件&#xff0c;它可以在用户需要登录的之前先将登录界面隐藏&#xff0c;只有当用户按下 CtrlAltDelete 之后才出现登录屏幕&#xff0c;这样可以防止那些模拟登录界面的程序获取密码信息…...

【目标检测】Anaconda+PyTorch配置

前言 本文主要介绍在windows系统上的Anaconda、PyTorch关键步骤安装&#xff0c;为使用yolo所需的环境配置完善。同时也算是记录下我的配置流程&#xff0c;为以后用到的时候能笔记查阅。 Anaconda 软件安装 Anaconda官网&#xff1a;https://www.anaconda.com/ 另外&#…...

什么是离线语音识别芯片?与在线语音识别的区别

离线语音识别芯片是一种不需要联网和其他外部设备支持&#xff0c;‌上电即可使用的语音识别系统。‌它的应用场合相对单一&#xff0c;‌主要适用于智能家电、‌语音遥控器、‌智能玩具等&#xff0c;‌以及车载声控和一部分智能家居。‌离线语音识别芯片的特点包括小词汇量、…...

使用Diffusion Models进行街景视频生成

Diffusion Models专栏文章汇总&#xff1a;入门与实战 前言&#xff1a;街景图生成相当有挑战性&#xff0c;目前的文本到视频的方法仅限于生成有限范围的场景的短视频&#xff0c;文本到3D的方法可以生成单独的对象但不是整个城市。除此之外街景图对一致性的要求相当高&#x…...

UFO:革新Windows操作系统交互的UI聚焦代理

人工智能咨询培训老师叶梓 转载标明出处 人机交互的便捷性和效率直接影响着我们的工作和生活质量。尽管现代操作系统如Windows提供了丰富的图形用户界面&#xff08;GUI&#xff09;&#xff0c;使得用户能够通过视觉和简单的点击操作来控制计算机&#xff0c;但随着应用程序功…...

scp免密复制文件

实现在服务器A和服务器B之间使用scp命令免密互相传输文件 1. 在服务器A中免密复制到服务器B 1.1 生成服务器A的公钥私钥 #在服务器A中执行 ssh-keygen -t rsa -P ""命令执行完毕会在服务器A的 ~/.ssh 目录下生成两个文件&#xff1a;id_rsa 和 id_rsa.pub 1.2 拷…...

Maven 的模块化开发示例

Maven 的模块化开发是一种非常有效的软件开发方式&#xff0c;它允许你将一个大型的项目分割成多个更小、更易于管理的模块&#xff08;modules&#xff09;。每个模块都可以独立地构建、测试和运行&#xff0c;这不仅提高了开发效率&#xff0c;也便于团队协作和项目的维护。以…...

Python爬虫实战:研究MechanicalSoup库相关技术

一、MechanicalSoup 库概述 1.1 库简介 MechanicalSoup 是一个 Python 库,专为自动化交互网站而设计。它结合了 requests 的 HTTP 请求能力和 BeautifulSoup 的 HTML 解析能力,提供了直观的 API,让我们可以像人类用户一样浏览网页、填写表单和提交请求。 1.2 主要功能特点…...

变量 varablie 声明- Rust 变量 let mut 声明与 C/C++ 变量声明对比分析

一、变量声明设计&#xff1a;let 与 mut 的哲学解析 Rust 采用 let 声明变量并通过 mut 显式标记可变性&#xff0c;这种设计体现了语言的核心哲学。以下是深度解析&#xff1a; 1.1 设计理念剖析 安全优先原则&#xff1a;默认不可变强制开发者明确声明意图 let x 5; …...

7.4.分块查找

一.分块查找的算法思想&#xff1a; 1.实例&#xff1a; 以上述图片的顺序表为例&#xff0c; 该顺序表的数据元素从整体来看是乱序的&#xff0c;但如果把这些数据元素分成一块一块的小区间&#xff0c; 第一个区间[0,1]索引上的数据元素都是小于等于10的&#xff0c; 第二…...

JavaScript 中的 ES|QL:利用 Apache Arrow 工具

作者&#xff1a;来自 Elastic Jeffrey Rengifo 学习如何将 ES|QL 与 JavaScript 的 Apache Arrow 客户端工具一起使用。 想获得 Elastic 认证吗&#xff1f;了解下一期 Elasticsearch Engineer 培训的时间吧&#xff01; Elasticsearch 拥有众多新功能&#xff0c;助你为自己…...

【Go】3、Go语言进阶与依赖管理

前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课&#xff0c;做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程&#xff0c;它的核心机制是 Goroutine 协程、Channel 通道&#xff0c;并基于CSP&#xff08;Communicating Sequential Processes&#xff0…...

有限自动机到正规文法转换器v1.0

1 项目简介 这是一个功能强大的有限自动机&#xff08;Finite Automaton, FA&#xff09;到正规文法&#xff08;Regular Grammar&#xff09;转换器&#xff0c;它配备了一个直观且完整的图形用户界面&#xff0c;使用户能够轻松地进行操作和观察。该程序基于编译原理中的经典…...

python执行测试用例,allure报乱码且未成功生成报告

allure执行测试用例时显示乱码&#xff1a;‘allure’ &#xfffd;&#xfffd;&#xfffd;&#xfffd;&#xfffd;ڲ&#xfffd;&#xfffd;&#xfffd;&#xfffd;ⲿ&#xfffd;&#xfffd;&#xfffd;Ҳ&#xfffd;&#xfffd;&#xfffd;ǿ&#xfffd;&am…...

HDFS分布式存储 zookeeper

hadoop介绍 狭义上hadoop是指apache的一款开源软件 用java语言实现开源框架&#xff0c;允许使用简单的变成模型跨计算机对大型集群进行分布式处理&#xff08;1.海量的数据存储 2.海量数据的计算&#xff09;Hadoop核心组件 hdfs&#xff08;分布式文件存储系统&#xff09;&a…...

Spring是如何解决Bean的循环依赖:三级缓存机制

1、什么是 Bean 的循环依赖 在 Spring框架中,Bean 的循环依赖是指多个 Bean 之间‌互相持有对方引用‌,形成闭环依赖关系的现象。 多个 Bean 的依赖关系构成环形链路,例如: 双向依赖:Bean A 依赖 Bean B,同时 Bean B 也依赖 Bean A(A↔B)。链条循环: Bean A → Bean…...

接口自动化测试:HttpRunner基础

相关文档 HttpRunner V3.x中文文档 HttpRunner 用户指南 使用HttpRunner 3.x实现接口自动化测试 HttpRunner介绍 HttpRunner 是一个开源的 API 测试工具&#xff0c;支持 HTTP(S)/HTTP2/WebSocket/RPC 等网络协议&#xff0c;涵盖接口测试、性能测试、数字体验监测等测试类型…...