嵌入式人工智能(9-基于树莓派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函数一样,对于这个问题,可以使用定时器来不断地显示,或者可以试试多线程,我这边没有做,后期我做好后,会再补充。

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

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

相关文章

N Puzzle (数字推盘游戏)

N Puzzle [数字推盘游戏] 1. 15 Puzzle2. N PuzzleReferences puzzle /ˈpʌzl/:n. 谜,智力游戏,疑问,不解之谜,令人费解的事 vt. 迷惑,使困惑1. 15 Puzzle https://en.wikipedia.org/wiki/15_puzzle The…

【Python脚本】读取execl表格域名到期时间进行筛选通过webhook进行通知

【Python脚本】读取execl表格域名到期时间进行筛选通过webhook进行通知 execl表格示例: import pandas as pd import requestsdf = pd.read_excel(D:\xx\xx\SSL.xlsx, sheet_name=None)webhook_url = "https://open.feishu.cn/open-apis/bot/v2/XXX?"for sheet_na…

高校如何拥抱国产化OS?中南民族大学信息化应用实践

CentOS 已然停服,数量众多的使用 CentOS 的企业以及高校,都面临着系统替换的迫切需求。国产化操作系统候选者众多,如何在兼顾原有系统兼容性的基础上,在国产化操作系统进行整体环境的平稳迁移,成为在选择 CentOS 替换方…

滑动窗口题目

题目描述&#xff1a; 计算两个字符串str1和str2在给定的含有n个元素的字符串数组strs中出现的最短距离。 详细解释&#xff1a; 定义整数变量n&#xff0c;用于存储字符串数组strs的长度。定义一个vector<string>类型的变量strs&#xff0c;用于存储输入的字符串。定义…

昇思25天学习打卡营第18天|RNN实现情感分类

相关知识 情感分类 指输入一段话或句子&#xff0c;返回该段话的正向或复兴的情感分类。 text embedding 指将文本转化成向量的方法。这里的文本指词、句子、文档等文本序列。 词向量化后会将词转为二进制(独热编码)或高维实数向量&#xff0c;句子和文档向量化则将句子或文…

SpringMVC注解全解析:构建高效Web应用的终极指南 (下)

一. 引言 在上篇文章中&#xff0c;我们介绍了几个重要的SpringMVC注解&#xff1a; SpringBootApplication&#xff1a;Spring Boot项目的启动类注解。RequestMapping&#xff1a;用于映射URL到控制器类或方法&#xff0c;支持多种请求方式。RequestParam&#xff1a;用于绑…

科研绘图系列:R语言分割小提琴图(Split-violin)

介绍 分割小提琴图(Split-violin plot)是一种数据可视化工具,它结合了小提琴图(violin plot)和箱线图(box plot)的特点。小提琴图是一种展示数据分布的图形,它通过在箱线图的两侧添加曲线来表示数据的密度分布,曲线的宽度表示数据点的密度。而分割小提琴图则是将小提…

41.ILA IP核集成逻辑分析仪在线调试工具

&#xff08;1&#xff09;逻辑分析仪使用场景&#xff1a; 仿真不全面数据交互存在异步情况板卡互联可靠性问题 (2)ILA使用方法&#xff1a; 使用IP核创建ILA调试环境使用Debug标记创建IP核使用路径标记核位置调试菜单创建ILA测试环境 (3)IP核调用过程&#xff1a; 例化模…

基于ssh的链接异常解决方法

VSCode、PyCharm链接异常 一.可能的原因 1.如果实例的系统盘重置或更换镜像&#xff0c;那么SSH的指纹会发生变化&#xff0c;于是SSH时会报错REMOTE HOST IDENTIFICATION HAS CHANGED 2.如果本地ssh config文件权限不对&#xff0c;会由于ssh时无法写入配置报错&#xff08;…

【BUG】已解决:IndexError: list index out of range

已解决&#xff1a;IndexError: list index out of range 欢迎来到英杰社区https://bbs.csdn.net/topics/617804998 欢迎来到我的主页&#xff0c;我是博主英杰&#xff0c;211科班出身&#xff0c;就职于医疗科技公司&#xff0c;热衷分享知识&#xff0c;武汉城市开发者社区主…

长难句打卡7.15

The trend was naturally most obvious in those areas of science based especially on a mathematical or laboratory training, and can be illustrated in terms of the development of geology in the United Kingdom 这一趋势自然在以数学或实验室训练为基础的科学领域里…

探寻大模型回答9.9和9.11犯错的根本原因

大家好,我是herosunly。985院校硕士毕业,现担任算法研究员一职,热衷于机器学习算法研究与应用。曾获得阿里云天池比赛第一名,CCF比赛第二名,科大讯飞比赛第三名。拥有多项发明专利。对机器学习和深度学习拥有自己独到的见解。曾经辅导过若干个非计算机专业的学生进入到算法…

养猫新手不会挑智能猫砂盆?2024最新挑选干货分享!

不得不说智能猫砂盆真的帮了我很大的忙&#xff0c;四年以来我陆陆续续养了很多的猫咪&#xff0c;但是因为需要上班&#xff0c;所以有时候也对铲屎的工作有些力不从心&#xff0c;后面听了朋友的建议&#xff0c;去入手了智能猫砂盆&#xff0c;不得不说买智能猫砂盆也非常的…

Java 8的变革:函数式编程和Lambda表达式探索

文章目录 一、函数接口二、Lambda表达式简介三、Lambda表达式外部参数四、Lambda范例五、Runnable Lambda表达式 一、函数接口 函数接口是一个具有单个抽象方法的接口&#xff0c;接口设计主要是为了支持 Lambda 表达式和方法引用&#xff0c;使得 Java 能更方便地实现函数式编…

【排序算法】—— 计数排序

一、简介 计数排序&#xff0c;顾名思义就是记录数据出现的次数进行排序&#xff0c;时间复杂度为O(NK)&#xff0c;空间复杂度为O(N)。只能用于整型&#xff0c;对于比较集中重复率比较高数据更为适用。 二、排序原理 比如对接下来这些数进行排序 arr[11] { 8,6,4,1,6,2,9,…

国产化低功耗HDMI转VGA方案,大量出货产品,广泛应用在显示器以及广告机产品

芯片描述&#xff1a; 兼具高性能和低成本效益的优点&#xff0c;是一款可以将高清视频 HDMI1.4 数字信号转换成 VGA 模拟信号输出的芯片。不需要提供外部电源&#xff0c;ICNM7301 就可以在正常模式下使用&#xff1b;ICNM7301 广 泛适用于各种市场系统和显示应用体系&#x…

Bash 学习摘录

文章目录 1、变量和参数的介绍&#xff08;1&#xff09;变量替换$(...) &#xff08;2&#xff09;特殊的变量类型export位置参数shift 2、引用&#xff08;1&#xff09;引用变量&#xff08;2&#xff09;转义 3、条件判断&#xff08;1&#xff09;条件测试结构&#xff08…

vue自定义折叠Tree,自定义折叠树

使用组件 <TreeNode v-for"(node, index) in nodes" :key"index" :node"node" />JSON数据 let nodes[{"id": 2030,"show_id": "MC1813024492270223360","detail_type": 1,"title": &…

Geometric Transformer for Fast and Robust Point Cloud Registration 论文解读

目录 一、导言 二、先导知识 1、超点匹配 2、KPConv 三、相关工作 1、基于对应的方法 2、直接配准方法 3、深度鲁棒估计 四、GeoTransformer模型 1、特征提取 2、超点匹配 几何自注意力模块 特征交叉注意力 计算高斯相关性 对应点采样 3、点匹配 4、局部到全局…

花开半夏,我决意仿一款答题小程序

不是清凉罢挥扇&#xff0c;自缘手倦歇些时。 ——杨万里&#xff08;宋&#xff09; 走过春的绚烂&#xff0c;路过初夏的清凉&#xff0c;我们迎来了炎炎夏日。蛙声阵阵&#xff0c;蝉鸣声声&#xff0c;稻花如白练&#xff0c;荷花别样红。 花开半夏&#xff0c;我决意仿一款…