51单片机快速入门之 IIC I2C通信
51单片机快速入门之 IIC 总线通信
协议:
- 空闲时 SCL/SDA 为高电平
- SCL高时 SDA下降沿 为开始信号
- 开始信号之后:
SCL高电平时 SDA不能变化 ,
SCL低电平时 SDA才可变
SDA 传数据时 从高到低按位传输 SCL一个脉冲高电平对应一位数据
4.SCL高电平时 SDA上升沿 为停止信号
数据格式:
1.单字节格式:
开始信号>数据(高到低)>应答(ACK)信号接收方SDA低电平>停止信号
2.多字节格式:
开始信号>发送设备地址和读写方向>应答(ACK)信号>数据传输>应答(ACK)信号接收方SDA低电平>停止信号
I2C 元器件 24c02(E^2PROM)
读/写操作:
1.单字节写流程:
开始信号>7位地址(1010固 0A 0B 0C)+读1/写0>24C02回复ACK信号>发送一个字节>ACK信号>停止信号
2.页写流程(多字节):
开始信号>7位地址(1010固 0A 0B 0C)+读1/写0>24C02回复ACK信号>发第一个字节数据地址>ACK>第一个字节数据>ACK>第二个字节数据...>一直到停止信号 或者16字节
最多可一次写入2-16字节!
超出会自动从初始位置覆盖数据 17时覆盖第一个字节数据,之后还有数据往后递增覆盖
3.立即地址读操作:
N范围(0~255)00H~FFH
开始信号>7位地址(1010固 0A 0B 0C)+读1/写0>ack回复>读取一个字节数据(上次操作地址N+1的数据)>停止信号
N=255时 下一个跳转读取 0
4.选择读操作:
任选地址读
开始信号>7位地址(1010固 0A 0B 0C)+读1/写0>低0伪写操作>ack>N字节地址>从ack>开始信号>7位地址(1010固 0A 0B 0C)+读1/写0>读信号 1>从ack>获取N地址下的数据>停止信号
5.连续读操作:
立即地址读操作 连续
开始信号>7位地址+读1>读取FFH(255)为第一个数据,>主ACK>00H>主ack...直到出现主ack不回复 停下来>停止信号才结束本次读取
选择读操作 连续
开始信号>7位地址(1010固 0A 0B 0C)+读1/写0>低0伪写操作>ack>N字节地址>从ack>开始信号>7位地址(1010固 0A 0B 0C)+读1/写0>读信号 1>从ack>获取N地址下的数据>ack>N+1数据>ack .....直到停止信号
电路图:
捣鼓了好几天,终于调试通了原来这元器件和书上的不同 所以说还是要多看看元器件数据手册才好,不然出了问题都找不到在哪! 就是这里 地址位我弄错了,书上很模糊所以我理解为
A0 A1 A2 顺序错了 实际上是A2 A1 A0
代码(简单发送):
#include <STC89C5xRC.H>//加载头文件,晶振12MHzsbit SCL=P2^0; //时钟线
sbit SDA=P2^1; //数据线void delay(unsigned int t); // 延时函数声明
void startI2C();//开始信号
void stopI2C();//停止信号void SendByte(unsigned char dat);//发送字节数据void main()
{SendByte(0xA2);//发送从机地址SendByte(0x00);//发送需要存入那个字节的地址 00H~FFHSendByte(0x44); //发送需要存储的数据 P17=0;模拟环境提示操作成功用 ,实际使用可删除while(1); // 防止程序重复运行
}void startI2C() //开始信号
{SDA=1; //首先拉高SDAdelay(10);//给他点时间SCL=1; //拉高SCLdelay(10); //1usSDA=0; //拉低SDA 触发开始信号delay(10); //1usSCL=0; //手动拉低确保时序准确 初始化以接受数据delay(10); //1us
}void stopI2C() //停止信号
{if(SCL==1&&SDA==0) //只有当SCL=1 而且SDA=0时才触发 SDA=0保证已经接受到ACK回复信号{delay(10); //等一会SDA=1; //拉高SDA ,上升沿触发停止信号} else if(SCL==0) //当SCL=0时,这句没啥用其实 ,防止 SCL=0 触发不了停止信号
{delay(10);SCL=1; //把scl 拉高if(SDA==0) //判断是否接收到ACK回复
{delay(10);SDA=1;}}}void SendByte(unsigned char dat)//发送字节数据
{unsigned char bita;startI2C();//发送开始信号for(bita=0; bita<8; bita++) {if((dat<<bita)&0x80) //每次根据bita 的值左移 bita位 再和 0x80(1000 0000) 与操作(只保最高位)
{SDA=1; //如果是1,拉高sda传送一个1 过去} else {SDA=0;// 反之给0}delay(10); //让它们稳定一下SCL=1;//上升读取 因开始信号已经拉低SCLdelay(10); //稳定时间 SCL=0; //下降写入数据 也可以说这是复位delay(10); //稳定时间} SDA=1; //8位传完就拉高等待ACK触发SCL=0; //下降写入数据 保证循环正确输出8位SCL=1; //拉高以配合ACK delay(10);//等待if(SDA!=1) //sda=0 证明 ack已回复 触发停止信号
{stopI2C();P30=0; //模拟环境提示操作成功用 ,实际使用可删除} else {P10=0;//模拟环境提示操作成功用 ,实际使用可删除}}void delay(unsigned int t) // 简单延迟函数
{while(t--);
}
运行效果:
程序设置了一个监视,操作成功会拉低P30
代码(简单读取):
#include <STC89C5xRC.H>sbit SCL=P2^0; //时钟线
sbit SDA=P2^1; //数据线
sbit DQ=P2^4;//读取按键
void delay(unsigned int t); // 延时函数声明
void startI2C();//开始信号
void stopI2C();//停止信号
bit x; //用于存储ACK信息
unsigned char u;void SendByte(unsigned char dat);//发送字节数据void main()
{SendByte(0xA2);//发送从机地址 最后一位置0 写入x=0;SendByte(0x01);//发送字节地址x=0;SendByte(0x66); //发送需要存储的数据if(x==1) {stopI2C(); //停止信号}P1=0;x=0;while(DQ==1);//阻断程序运行,当按钮按下往下执行//按键判断读取并赋值给P1寄存器if(DQ==0) {SendByte(0xA3);//发送从机地址 最后一位置1 实际读取if(x==1) { //表示读取请求被响应unsigned char red,bint;P33=0;red=0;// 在读取数据的循环之前添加SDA释放if(SDA!=1&&SCL!=1) {SDA = 1; // 释放SDA线delay(0);}// 读取数据的循环for(bint=0; bint<8; bint++) {delay(20);//延时等待SCL=0;//读取数据delay(20);//延时等待SCL=1;//delay(20);// 检查SDA状态,并更新red的值if(SDA==1) { //如果读取到高电平red |=1<<(7 - bint); // 设置对应位为1} else {red |=0<<(7-bint);}delay(10);//延时等待}SCL=0;//读取数据delay(10);//延时等待SDA = 1; // nackdelay(10);P1=red;//把获取到的值直接用到P1中stopI2C(); //停止信号}}while(1); // 防止程序重复运行
}void startI2C()
{SDA=1;delay(10);SCL=1;delay(10); //1usSDA=0;delay(10); //1usSCL=0; //手动拉低确保时序准确delay(10); //1us
}void stopI2C()
{if(SCL==1&&SDA==0) {delay(10);SDA=1;} else if(SCL==0) {delay(10);SCL=1;if(SDA==0) {delay(10);SDA=1;}}}void SendByte(unsigned char dat)//发送字节数据
{unsigned char bita;startI2C();//发送开始信号for(bita=0; bita<8; bita++) {if((dat<<bita)&0x80) {SDA=1;} else {SDA=0;}delay(10);SCL=1;//上升读取 因开始信号已经拉低SCLdelay(10);SCL=0; //下降写入数据delay(10);}SDA=1;SCL=0; //下降写入数据 保证循环正确输出8位SCL=1;delay(10);if(SDA==0) {x=1; //有回复为1P30=0;} else {x=0; //无回复为0// P10=0;}}void delay(unsigned int t) // 简单延迟函数
{while(t--);
}
读取运行效果 :
由图可以看出,元器件根本没有回复数据(试过选择地址读取,也没效果) 所以就这样吧!
最后更新于2024/10/24 0:01
相关文章:
51单片机快速入门之 IIC I2C通信
51单片机快速入门之 IIC 总线通信 协议: 空闲时 SCL/SDA 为高电平SCL高时 SDA下降沿 为开始信号开始信号之后: SCL高电平时 SDA不能变化 , SCL低电平时 SDA才可变 SDA 传数据时 从高到低按位传输 SCL一个脉冲高电平对应一位数据 4.SCL高电平时 SDA上升沿 为停止信号 数…...
腾讯推出ima.copilot智能工作台产品 由混元大模型提供技术支持
腾讯公司近期推出了一款名为ima.copilot(简称ima)的智能工作台产品,它由腾讯混元大模型提供技术支持。这款产品旨在通过其会思考的知识库,为用户开启搜读写的新体验。ima.copilot的核心功能包括知识获取、打造专属知识库以及智能写…...
1024是什么日子
【1024程序员日数字编织梦想的赞歌】 在这个由二进制构建的宇宙里,每一行代码都是通往未来的桥梁,每一位程序员都是这浩瀚数字海洋中的航海家。今天,10月24日,不仅是一个简单的日期,它是属于我们的节日——程序员日&a…...
驱动开发系列20 - Linux Graphics Xorg-server 介绍
一: 概述 X.Org Server 是由 X.Org 基金会管理的 X Window System (X11) 显示服务器的自由开源实现。客户端 X Window System 协议的实现以 X11 库的形式存在,这些库作为与 X 服务器通信的有用 API。有两个主要的 X11 库。第一个库是 Xlib,它是最初的 C 语言 X11 API;…...
晶台推出SOP5封装的高速光耦KLM45X,提供1MBit/s超快速率
KLM452 和 KLM453 器件均由一个红外发射二极管与一个高速光电检测晶体管组成,两者之间光学耦合。光电二极管偏置和输出晶体管集电极的独立连接可以通过减少输入晶体管的基极-集电极电容来使速度比传统的光电晶体管耦合器提高几个数量级。它们采用行业内标准的 5 引脚…...
软物质流变探究:从宏观微观差异,到水凝胶界面特性
大家好!今天我们要探讨的是一篇关于纳米级界面水凝胶粘弹性的研究论文——《Nanoscopic Interfacial Hydrogel Viscoelasticity Revealed from Comparison of Macroscopic and Microscopic Rheology》发表于《Nano Letters》,该研究通过比较宏观和微观流…...
Axure中继器单选、多选和重置
亲爱的小伙伴,在您浏览之前,烦请关注一下,在此深表感谢! 课程主题:Axure中继器单选、多选和重置 主要内容:根据查询条件,通过单选、多选和重置,从中继器中得到数据 应用场景&…...
微软公司用没有使用证据的商标申请驰名商标,该怎么维权?
收集证据:首先需要收集微软公司商标使用的证据,包括但不限于销售记录、广告宣传材料、市场调查报告等,以证明商标的实际使用情况和知名度。如果微软公司的商标确实没有在市场上使用,或者使用证据不足以证明其商标的知名度…...
学习分布式系统我来助你!【基本知识、基础理论、设计模式、应用场景、工程应用、缓存等全包含!】
基本知识 什么是分布式 分布式系统是一种通过网络连接多个独立计算机节点,共同协作完成任务的系统架构,具有高度的可扩展性、容错性和并发处理能力,广泛应用于大数据处理、云计算、分布式数据库等领域。 通俗来讲:分布式系统就…...
ubuntu查看系统版本命令
查看系统版本指令 在 Ubuntu 操作系统中,您可以使用多个命令来查看系统版本。以下是一些常用的命令: lsb_release -a 这个命令会显示详细的 Ubuntu 版本信息,包括发行版名称、版本号、代号等。lsb_release -acat /etc/os-release 这个命令会显…...
使用yield压平嵌套字典有多简单?
我们经常遇到各种字典套字典的数据,例如: nest_dict {a: 1,b: {c: 2,d: 3,e: {f: 4}},g: {h: 5},i: 6,j: {k: {l: {m: 8}}} } 有没有什么简单的办法,把它压扁,变成: {a: 1,b_c: 2,b_d: 3,b_e_f: 4,g_h: 5,i: 6,j_k_l_…...
express中使用morgan打印请求数据日志文件,按日期分割
使用morgan可以打印日志,但是要分割日志文件就需要使用file-stream-rotator,下面介绍使用方法: 1.安装2个依赖 npm i morgan file-stream-rotator 2.在入口文件app.js中引入相关插件 var express require("express"); var fs require("fs"); var pat…...
干货 | 2024 AI+智慧城市安全解决方案白皮书(免费下载)
导读:新型智慧城市是推动城市治理体系和治理能力现代化、提升城市居民幸 福感和满意度的新理念和新路径,也是网络强国建设和数字经济发展的重要载体。随着 AI 技术的不断发展和在智慧城市智领域广泛的应用,人们享受技 术红利的同时࿰…...
超越 React Query:探索更高效的数据请求策略
我们常常遇到组件间通信的难题。你是否也曾为如何优雅地在组件间传递信息而头疼?今天,我想和大家分享一个让我眼前一亮的解决方案——使用 alova。 跨组件触发请求的挑战 如果你正在构建一个电商应用,用户在更新了购物车后,需要…...
Scala trait
一.trait 基本使用 idea实例 二.实现单个特质 三.实现多个特质 idea实例 四.特质成员的处理方式...
AI大法之C语言哈希表算法比较两个文件去重
最近朋友在工作上遇到了一个问题,经常需要比对两个文件,筛选出文件中不同的订单号。比如有两个文件:计费.txt 和 受理.txt,文件中每一行都是一个订单号,需要找出计费.txt文件中有而受理.txt文件中没有的单号和计费.txt…...
Scala 提取器(Extractor)
Scala 提取器(Extractor) Scala 提取器(Extractor)是一个非常有用的特性,它允许你为任何类型定义自定义的解构赋值语法。在Scala中,提取器是一种用于从对象中提取值的工具,它可以帮助你以一种更直观和声明式的方式处理数据。本文将详细介绍Scala提取器的工作原理、使用场景…...
【主机漏洞扫描常见修复方案】:Tomcat安全(机房对外Web服务扫描)
文章目录 引言I SSL/TLS Not ImplementedTomcat 服务器 SSL 证书安装部署(JKS 格式)Tomcat 服务器 SSL 证书安装部署(PFX 格式)HTTP 自动跳转 HTTPS 的安全配置(可选)修复SSL证书版本低II 主机漏洞扫描常见修复方案Apache JServ protocol serviceSlow HTTP DEnial of Ser…...
MySQL数据库之——事务(Transaction)详解
一、MySQL 事务定义 MySQL 事务主要用于处理操作量大,复杂度高的数据。比如说,在银行管理系统中,用户张三向李四账户转账的操作,账户转账是一个完整的业务,最小的单元,不可再分,这样,…...
LabVIEW提高开发效率技巧----事件日志记录
在LabVIEW开发中,集成事件日志记录系统是提升程序调试效率和确保系统运行稳定的关键步骤。通过记录关键操作和异常事件,开发人员可以快速定位问题、优化程序性能,并确保系统的稳定性和可靠性。 1. 事件日志的作用 事件日志是指在程序运行过…...
整合XXL-Job任务调度平台
创建数据库 tables_xxl_job.sql 引入依赖 <dependency><groupId>com.xuxueli</groupId><artifactId>xxl-job-core</artifactId><version>2.4.0</version> </dependency>编写配置文件 server:port: 8081xxl:job:admin:# 这…...
hi3536上ffmpeg带rtmp移植
1.下载ffmpeg-4.1.3版本源码包 用下面的脚本进行configure: ./configure \--target-oslinux \--prefix./libs/ \--enable-cross-compile \--archarm \--ccarm-hisiv500-linux-gcc \--cross-prefixarm-hisiv500-linux- \--nmarm-hisiv500-linux-nm \--enable-share…...
在PHP中,读取大文件
在PHP中,读取大文件可以采用以下几种方法: 1. 使用fopen和fread函数:这是最基本的文件读取方法,可以逐行读取大文件。首先使用fopen函数打开文件,然后使用fread函数指定读取的字节数,逐行读取文件内容并进…...
N-gram详解
文章目录 一、什么是N-gram?二、N-gram的种类三、优缺点PS:补充 一、什么是N-gram? 在自然语言处理中,n-gram是一种重要的文本表示方法。n-gram是指给定文本中连续的n个项目,这些项目可以是声音、单词、字符或者像素等。n-gram模型常常用于…...
电路中的电源轨及地的区别和处理
电源轨 VCC 通常代指正电源供电轨。在大多数数字和模拟电路中,VCC代表电路中的正电源端。VCC提供电路所需的正电压,通常是用来驱动晶体管、集成电路。 VDD 相对与VCC的正电源供应,VDD更常用于表示数字电路中的正电源引脚。VDD常见于集成电…...
k8s可以部署私有云吗?私有云部署全攻略
k8s可以部署私有云吗?K8S可以部署私有云。Kubernetes是一个开源的容器编排引擎,能够自动化容器的部署、扩展和管理,使得应用可以在各种环境中高效运行。通过使用Kubernetes,企业可以在自己的数据中心或私有云环境中搭建和管理容器…...
编辑器资源管理器
解释 EditorResMgr 是一个用于在 Unity 编辑器中加载资源的管理器。它通过 Unity 编辑器的 API (AssetDatabase) 进行资源加载,但仅在开发和编辑模式下可用,不能在最终发布的游戏中使用。这种工具通常用来在开发过程中快速加载编辑器中的资源࿰…...
高性能数据分析利器DuckDB在Python中的使用
DuckDB具有极强的单机数据分析性能表现,功能丰富,具有诸多拓展插件,且除了默认的SQL查询方式外,还非常友好地支持在Python、R、Java、Node.js等语言环境下使用,特别是在Python中使用非常的灵活方便。 安装 pip insta…...
IAR全面支持旗芯微车规级MCU,打造智能安全的未来汽车
中国上海,2024年10月18日 — 在全球汽车电子快速发展的今天,IAR与苏州旗芯微半导体有限公司(以下简称“旗芯微”)联合宣布了一项激动人心的合作——IAR Embedded Workbench for Arm 9.60.2版本现已全面支持旗芯微车规级MCU&#x…...
**深入浅出:TOGAF中的应用架构**
摘要: 在企业架构(EA)领域,TOGAF(The Open Group Architecture Framework)是一个广泛应用的框架。本文将带你深入了解TOGAF中的应用架构,帮助你理解其核心概念和实际应用。无论你是初学者还是有…...
flask 简易网站开发/济南今日头条最新消息
如何查看存款和贷款的基准利率 点击中国人民银行官网点击利率点击利率水平点击即可查看...
网站access数据怎么做/网络推广网站
为什么80%的码农都做不了架构师?>>> Git是一种分布式的版本控制系统. 什么是版本?每次编辑之后的文档就是一个版本。 什么是版本控制?版本控制就是对每次修改后的这个版本的文档进行操控。 Git的目的在于减轻工作负担,…...
网站申请域名/就业seo好还是sem
仿函数概念 仿函数(functor),就是使一个类的使用看上去像一个函数。其实现就是类中实现一个operator(),这个类就有了类似函数的行为,就是一个仿函数类了。 尽管函数指针被广泛用于实现函数回调,但C还提供了一个重要的实现回调函数…...
班级网站建设/专业的网站建设公司
Ctrl/ 或 CtrlShift/注释(// 或者/*…*/ )ShiftF6重构-重命名CtrlX删除行CtrlD复制行CtrlG查找行CtrlShiftUp/Down代码向上/下移动。F2 或ShiftF2高亮错误或警告快速定位写代码,按Tab生成代码选中文本,按CtrlShiftF7高亮显示所有该…...
怎么样做销往非洲太阳能板的网站/谷歌浏览器 官网下载
点击此处:官网下载根据自己的系统 ,下载相应的JDK版本。1. JDK1.8安装1.双击下载的安装包(.exe文件),进行安装。2.点击“下一步”3.这里可以自行选择安装目录,笔者选择安装在D盘。点击“更改”,进入文件夹,…...
从零开始建设企业网站/简阳seo排名优化课程
成交量(VOL)作为市场较为重要的指标之一,其量增量缩影响着价格的变动,亦看做是多空双方博弈的结果。那么如何洞察成交量(VOL)以进行交易呢? 首先我们先了解成交量(VOL)&…...