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. 事件日志的作用 事件日志是指在程序运行过…...
【MySQL】《MySQL索引核心分类面试高频考点问答清单》(附:《一页纸速记版》)
文章目录《MySQL索引核心分类面试高频考点问答清单》一、基础概念类(入门必问)Q1:MySQL索引的本质是什么?核心作用有哪些?Q2:MySQL常用的索引数据结构有哪些?各自特点是什么?Q3&…...
Midjourney油彩模式正在悄悄升级!内部测试通道流出的--oil-mode beta参数文档(含笔触方向控制与亚麻布基底模拟指令)
更多请点击: https://intelliparadigm.com 第一章:Midjourney油彩模式的演进脉络与beta通道解密 Midjourney 的油彩模式(Oil Painting Mode)并非官方命名的功能,而是社区对一组特定风格化参数组合的统称,…...
为什么92%的AI团队Serverless化失败?奇点大会披露的4个反直觉架构断点与实时熔断方案
更多请点击: https://intelliparadigm.com 第一章:AI原生Serverless实践:2026奇点智能技术大会无服务器架构 在2026奇点智能技术大会上,AI原生Serverless成为核心范式——它不再将模型推理简单托管于函数即服务(FaaS&…...
终局架构:指纹隔离底座 + gRPC分布式调度,重塑千万级拼多多店群RPA集群
大家好,我是林焱,一名专注电商底层业务逻辑与 RPA 自动化架构定制的独立开发者。 在前面的几篇 CSDN 专栏中,我们探讨了如何利用“指纹浏览器底层隔离”解决风控关联问题,如何利用“EDA(事件驱动)”和“CD…...
2026年市面上的培训机构管理系统对比,谁才是性价比之王
教务是培训机构的 “心脏”,而排课是教务最核心、最耗时、最容易出错的环节。传统人工排课:打开 Excel,手动填教师、教室、学员、时间,反复核对冲突,排一周课表要 1–3 天,还经常出现:老师时间撞…...
潜变量模型完全指南:从高斯混合模型到变分自编码器
潜变量模型完全指南:从高斯混合模型到变分自编码器 【免费下载链接】bayesian-machine-learning Notebooks about Bayesian methods for machine learning 项目地址: https://gitcode.com/gh_mirrors/ba/bayesian-machine-learning 潜变量模型是机器学习领域…...
【Midjourney×Photoshop黄金工作流】:20年Adobe+AI实战专家亲授5步无缝整合法,97%设计师尚未掌握的智能修图新范式
更多请点击: https://intelliparadigm.com 第一章:MidjourneyPhotoshop黄金工作流的范式革命 传统图像创作正经历一场静默却深刻的重构——当 Midjourney 生成的高语义图像与 Photoshop 的像素级控制能力深度耦合,工作流不再只是“AI出图→人…...
AI小白必看:打好基础再冲大模型,收藏这份学习路线图!
本文针对想学习AI的学生,强调掌握基础的重要性,避免直接进入大模型学习。文章提出应先理解AI的核心是让机器从数据中学习规律,并掌握数学、编程和数据思维能力。建议从数据处理开始,熟悉Python及常用库,逐步学习机器学…...
Musa并行搜索工具:重塑信息检索工作流,提升多源对比效率
1. 项目概述:重新定义你的搜索工作流如果你和我一样,每天的工作都离不开在浏览器里反复横跳——为了一个技术问题,先在 Google 搜一遍,再去 Stack Overflow 看看有没有新答案,接着打开 ChatGPT 问问它的看法࿰…...
告别驱动开发:手把手教你用himm工具在用户空间玩转Hi3516的GPIO
用户空间高效操控Hi3516 GPIO:himm工具实战指南 在嵌入式开发领域,传统的内核驱动开发往往需要经历漫长的编译、加载和调试周期。对于快速硬件验证和原型开发而言,这种开发模式显得过于笨重。海思Hi3516平台提供的himm工具,为开发…...
