【STC15单片机】模拟I2C操作AT24C02数据读取【更新中】
目录
I2C时序结构
I2C代码
AT24C02代码(继承I2C底层代码)
PCF8591

PCB上线的长短可能影响数据传输的时间,写I2C时序可能就要加一点延时
I2C时序结构
- 起始条件:SCL高电平期间,SDA从高电平切换到低电平
- 终止条件:SCL高电平期间,SDA从低电平切换到高电平

发送一个字节:SCL低电平期间,主机将数据位依次放到SDA线上(高位在前),然后拉高SCL,从机将在SCL高电平期间读取数据位,素有SCL高电平期间SDA不允许有数据变化,依次循环上述过程8次,即可发送一个字节

接收一个字节:SCL低电平期间,从机将数据位依次放到SDA线上(高位在前),然后拉高SCL,主机将在SCL高电平期间读取数据位,所以SCL高电平期间SDA不允许有数据变化,依次循环上述过程8次,即可接收一个字节(主机在接收之前,需要释放SDA)

- 发送应答:在接收完一个字节之后,主机在下一个时钟发送一位数据,数据0表示应答,数据1表示非应答
- 接收应答:在发送完一个字节之后,主机在下一个时钟接收一位数据,判断从机是否应答,数据0表示应答,数据1表示非应答(主机在接收前,需要释放SDA)

I2C代码
#include "I2C.h"//15开发板中AT24C02的IIC通信引脚
sbit I2C_SDA = P2^1;
sbit I2C_SCL = P2^0;/*** @brief I2C起始信号* @param 无* @retval 无*/
void I2C_Start(void)
{I2C_SDA = 1; //拼接其他块,确保默认是1I2C_SCL = 1;I2C_SDA = 0; //时序上先拉低I2C_SCL = 0;
}/*** @brief I2C停止信号* @param 无* @retval 无*/
void I2C_Stop(void)
{I2C_SDA = 0; //确保默认0,保证由低电平拉高至高电平I2C_SCL = 1;I2C_SDA = 1;
}/*** @brief I2C发送一个字节数据* @param Byte 要发送的字节* @retval 无*/
void I2C_SendByte(unsigned char Byte)
{unsigned char i;
// I2C_SCL = 0; //起始信号已经拉低了,无需重复for (i = 0; i < 8; i ++){ I2C_SDA = Byte & (0x80>>i); //把Byte最高位取出,赋值给I2C_SDA,依次从高到底I2C_SCL = 1;
// _nop_();_nop_();_nop_();_nop_();_nop_();//需要0.4usI2C_SCL = 0;}
}/*** @brief I2C接收一个字节数据* @param 无* @retval 接受到的一个字节数据 */
unsigned char I2C_ReceiveByte(void)
{unsigned char i,Byte=0x00;I2C_SDA = 1; //接收之前,先把I2C_SDA置1,释放总线for(i=0;i<8;i++){I2C_SCL = 1; //拉高SCL,SCL读取SDAif(I2C_SDA == 1){Byte |= (0x80>>i);}/*如果读取到的SDA为1,把Byte最高位置1,如果读取到的SDA为0,不处理,默认最高位为0,放在循环里从高位到低位依次读取*/I2C_SCL = 0; //拉低SCL,结束当前循环}return Byte;
}/*** @brief I2C发送应答* @param AckBit 应答位,0为应答,1为非应答* @retval 无*/
void I2C_SendAck(unsigned char AckBit)
{ I2C_SDA = AckBit;//给应答就是0,不给应答就是1I2C_SCL = 1;I2C_SCL = 0;
}/*** @brief I2C接收应答* @param 无* @retval 接收到的应答位,0为应答,1为非应答*/
unsigned char I2C_ReceiveAck(void)
{unsigned char AckBit;I2C_SDA = 1; //先释放SDAI2C_SCL = 1; //高电平期间读取SDAAckBit=I2C_SDA; //读取到什么,就返回什么I2C_SCL = 0;return AckBit; //返回0,代表有应答,返回1,代表无应答
}
#ifndef __I2C_H__
#define __I2C_H__#include <STC15F2K60S2.H>
#include "intrins.h"void I2C_Start(void);
void I2C_Stop(void);
void I2C_SendByte(unsigned char Byte);
unsigned char I2C_ReceiveByte(void);
void I2C_SendAck(unsigned char AckBit);
unsigned char I2C_ReceiveAck(void);#endif

AT24C02设备地址:

A2A1A0这三个引脚是用来扩展的,如果不用就默认是000
所以默认设备地址是10100000(0xA0 写数据),10100001(0xA1 读数据)
AT24C02代码(继承I2C底层代码)
#include "AT24C02.h"#define AT24C02_ADDRESS 0xA0 //从机地址+写 1010 0000/***@brief 名称:AT24C02写入一个字节*@param 参数:WordAddess 要写入字节的地址(0~255)*@param 参数: Data 要写入的数据*@retval返回值:无*/
void AT24C02_WriteByte(unsigned char WordAddress, unsigned char Data)
{
// unsigned char Ack;I2C_Start();I2C_SendByte(AT24C02_ADDRESS);//从机地址+写
// Ack = I2C_ReceiveAck();
// if(Ack == 0)
// {
// P2 = 0x80; // 1000 0000
// P0 = 0x00;
// } //先测试是否有应答,定义的Ack被I2C_ReceiveAck();赋值,然后就可以测试了I2C_ReceiveAck();I2C_SendByte(WordAddress); //要写入数据的地址I2C_ReceiveAck();I2C_SendByte(Data); //写入数据I2C_ReceiveAck();I2C_Stop();
}/***@brief 名称:AT24C02读取一个字节*@param 参数:WordAddess 要读出字节的地址*@retval返回值:读出的数据*/
unsigned char AT24C02_ReadByte(unsigned char WordAddess)
{unsigned char Data;I2C_Start();I2C_SendByte(AT24C02_ADDRESS); //从机地址+写I2C_ReceiveAck(); //接受应答I2C_SendByte(WordAddess); //数据的地址I2C_ReceiveAck();I2C_Start();I2C_SendByte(AT24C02_ADDRESS | 0x01);//发送从机地址+读本函数第二个函数,或上0x01变成读地址(0xA1)I2C_ReceiveAck();Data = I2C_ReceiveByte();I2C_SendAck(1); //不发送应答I2C_Stop();return Data;
}
#ifndef __AT24C02_H__
#define __AT24C02_H__#include <STC15F2K60S2.H>
#include "I2C.h"void AT24C02_WriteByte(unsigned char WordAddress, unsigned char Data);
unsigned char AT24C02_ReadByte(unsigned char WordAddress);#endif
测试:先写入,不读取,然后下载只读取的函数,如果读出数值没有问题,那就正确了
#include <STC15F2K60S2.H>
#include "smg.h"
#include "I2C.h"
#include "AT24C02.h"unsigned char Data;void main()
{All_Init();AT24C02_WriteByte(0,88);Delay_ms(5); //写数据的周期 5msData = AT24C02_ReadByte(0); while(1){Nixie(1,Data/10);Nixie(2,Data%10);}
}
PCF8591

PCF8591地址:1001 0000(0x90 写),1001 0001(0x91 读)

支持四路AD转换(模拟信号转数字信号),支持一路DA转换(数字信号转模拟信号)

程序有问题,不粘贴了,调成功了在粘贴过来
学习资料:
江科大自化协---51单片机入门教程-2020版 程序全程纯手打 从零开始入门【12-2】

相关文章:
【STC15单片机】模拟I2C操作AT24C02数据读取【更新中】
目录 I2C时序结构 I2C代码 AT24C02代码(继承I2C底层代码) PCF8591 PCB上线的长短可能影响数据传输的时间,写I2C时序可能就要加一点延时 I2C时序结构 起始条件:SCL高电平期间,SDA从高电平切换到低电平终止条件&…...
Hadoop
Hadoop Hadoop1.x 2.x 3.x区别 Hadoop1.x组成:MapReduce负责计算和资源调度,HDFS负责数据存储,Common辅助工具。 Hadoop2.x组成:MapReduce负责计算,Yarn负责资源调度,HDFS负责数据存储,Commo…...
ArrayList源码+扩容机制分析
1. ArrayList 简介 ArrayList 的底层是数组队列,相当于动态数组。与 Java 中的数组相比,它的容量能动态增长。在添加大量元素前,应用程序可以使用ensureCapacity操作来增加 ArrayList 实例的容量。这可以减少递增式再分配的数量。 ArrayLis…...
数据库(第四次作业)
学生表:Student (Sno, Sname, Ssex , Sage, Sdept) 学号,姓名,性别,年龄,所在系 Sno为主键 课程表:Course (Cno, Cname,) 课程号,课程名 Cno为主键 学生选课表:SC (Sno, Cno, Score)…...
传统档案管理,为什么影响企业上市进度?
企业上市,对于很多创业者来说,是他们奋发努力的首要目标。企业通过上市,进行股权融资,扩大经营规模,加速促进公司成长,最终达到企业的可持续发展。而要实现成功上市,企业除了需要满足股份公司上…...
9个EXCEL舍入函数公式的用法和实例
用法和实例 1. ROUND ROUND函数可以将数字四舍五入到指定的小数位数。 语法:ROUND(number, num_digits) number:要四舍五入的数字。 num_digits:要保留的小数位数。 举例: ROUND(3.14159,2),结果为3.14 ROUND(3.141…...
设计模式:代理模式给原始类附加功能
一、代理模式 1、定义 在不改变原始类(被代理类)的情况下,通过引入代理类来给原始类附加功能。 一般情况下,让代理类和原始类实现同样的接口。 但是,如果原始类并没有定义接口,并且原始类代码并不是我们…...
JavaScript刷LeetCode拿offer-链表篇
一、链表 链表(Linked List)是一种常见的基础数据结构,也是线性表的一种。 一个线性表是 n 个具有相同特性的数据元素的有限序列,线性表的存储结构分为两类:顺序表(数组)和链表。 链表相比较顺…...
CPP2022-28-期末模拟测试01
6-1 实现一个计算三角形面积的简单函数(假设输入的边长合理)。 分数 10 全屏浏览题目 切换布局 作者 王和兴 单位 东北大学秦皇岛分校 实现一个计算三角形面积的简单函数(假设输入的边长合理)。 函数接口定义: do…...
牛客网Python篇数据分析习题(五)
1.现有牛客网12月每天练习题目的数据集nowcoder.csv。包含如下字段(字段之间用逗号分隔): user_id:用户id question_id:问题编号 result:运行结果 date:练习日期 请你统计答对和答错的总数分别是多少。 imp…...
华为OD机试真题JAVA实现【人数最多的站点】真题+解题思路+代码(20222023)
🔥系列专栏 华为OD机试(JAVA)真题目录汇总华为OD机试(Python)真题目录汇总华为OD机试(C++)真题目录汇总华为OD机试(JavaScript)真题目录汇总文章目录 🔥系列专栏题目输入输出示例一输入输出说明解题思路核心知识点Code运行结果版权说...
ROS2机器人编程简述humble-第四章-IMPROVED DETECTOR .4
ROS2之TF2小练习-颜色随机器人和障碍物直接距离变化ROS2之TF2小练习-有哪些bug找找看里面给出了:ROS2机器人编程简述humble-第四章-BASIC DETECTOR .3需要改进哪些地方呢?检测之后,距离不变了……如何变化?这个问题可以问chatgpt吗…...
依存句法分析 -- tag和dep释义
依存句法分析(Dependency Parsing, DP)是通过分析语言单位内成分之间的依存关系揭示其句法结构,主张橘子 中核心动词是支配其它成分的中心成分,而它本身却不受其他任何成分的支配,所有受支配成分都以某种关系从属于支配…...
服务器常见的网络攻击以及防御方法
网络安全威胁类别 网络内部的威胁,网络的滥用,没有安全意识的员工,黑客,骇客。 木马攻击原理 C/S 架构,服务器端被植入目标主机,服务器端通过反弹连接和客户端连接。从而客户端对其进行控制。 病毒 一…...
Python期末复习知识点大合集(期末不挂科版)
Python期末复习知识点大合集(期末不挂科版) 文章目录Python期末复习知识点大合集(期末不挂科版)一、输入及类型转换二、格式化输出:字符串的format方法三、流程控制四、随机数生成五、字符串六、序列索(含字…...
Echarts 雷达图设置拐点大小和形状,tooltip后文字不居中对齐
第017个点击查看专栏目录Echarts的雷达图的拐点大小和形状是可以设置的,在series中设置symbol 相应的属性即可。 使用tooltip的时候,默认状态文字是居中对齐的,不好看。需要在tooltip属性中设置一下,如图所示,效果比较…...
Lesson 7.1 无监督学习算法与 K-Means 快速聚类
文章目录一、聚类算法与无监督学习二、K-Means 快速聚类的算法原理1. K-Means 快速聚类的基本执行流程2. K-Means 快速聚类的背后的数学意义三、K-Means 快速聚类的 sklearn 实现方法1. sklearn 中实现 K-Means 快速快速聚类2. 轮廓系数基本概念与 sklearn 中实现方法从现在开始…...
优维低代码:Legacy Templates 构件模板
优维低代码技术专栏,是一个全新的、技术为主的专栏,由优维技术委员会成员执笔,基于优维7年低代码技术研发及运维成果,主要介绍低代码相关的技术原理及架构逻辑,目的是给广大运维人提供一个技术交流与学习的平台。 连载…...
最全面的SpringBoot教程(五)——整合框架
前言 本文为 最全面的SpringBoot教程(五)——整合框架 相关知识,下边将对SpringBoot整合Junit,SpringBoot整合Mybatis,SpringBoot整合Redis等进行详尽介绍~ 📌博主主页:小新要变强 的主页 &…...
信息安全保障
信息安全保障信息安全保障基础信息安全保障背景信息安全保障概念与模型基于时间的PDR模型PPDR模型(时间)IATF模型--深度防御保障模型(空间)信息安全保障实践我国信息安全保障实践各国信息安全保障我国信息安全保障体系信息安全保障…...
深入浅出:JavaScript 中的 `window.crypto.getRandomValues()` 方法
深入浅出:JavaScript 中的 window.crypto.getRandomValues() 方法 在现代 Web 开发中,随机数的生成看似简单,却隐藏着许多玄机。无论是生成密码、加密密钥,还是创建安全令牌,随机数的质量直接关系到系统的安全性。Jav…...
【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)
服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...
python如何将word的doc另存为docx
将 DOCX 文件另存为 DOCX 格式(Python 实现) 在 Python 中,你可以使用 python-docx 库来操作 Word 文档。不过需要注意的是,.doc 是旧的 Word 格式,而 .docx 是新的基于 XML 的格式。python-docx 只能处理 .docx 格式…...
华为云Flexus+DeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建
华为云FlexusDeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建 前言 如今大模型其性能出色,华为云 ModelArts Studio_MaaS大模型即服务平台华为云内置了大模型,能助力我们轻松驾驭 DeepSeek-V3/R1,本文中将分享如何…...
代理篇12|深入理解 Vite中的Proxy接口代理配置
在前端开发中,常常会遇到 跨域请求接口 的情况。为了解决这个问题,Vite 和 Webpack 都提供了 proxy 代理功能,用于将本地开发请求转发到后端服务器。 什么是代理(proxy)? 代理是在开发过程中,前端项目通过开发服务器,将指定的请求“转发”到真实的后端服务器,从而绕…...
零基础在实践中学习网络安全-皮卡丘靶场(第九期-Unsafe Fileupload模块)(yakit方式)
本期内容并不是很难,相信大家会学的很愉快,当然对于有后端基础的朋友来说,本期内容更加容易了解,当然没有基础的也别担心,本期内容会详细解释有关内容 本期用到的软件:yakit(因为经过之前好多期…...
Hive 存储格式深度解析:从 TextFile 到 ORC,如何选对数据存储方案?
在大数据处理领域,Hive 作为 Hadoop 生态中重要的数据仓库工具,其存储格式的选择直接影响数据存储成本、查询效率和计算资源消耗。面对 TextFile、SequenceFile、Parquet、RCFile、ORC 等多种存储格式,很多开发者常常陷入选择困境。本文将从底…...
HDFS分布式存储 zookeeper
hadoop介绍 狭义上hadoop是指apache的一款开源软件 用java语言实现开源框架,允许使用简单的变成模型跨计算机对大型集群进行分布式处理(1.海量的数据存储 2.海量数据的计算)Hadoop核心组件 hdfs(分布式文件存储系统)&a…...
Python Ovito统计金刚石结构数量
大家好,我是小马老师。 本文介绍python ovito方法统计金刚石结构的方法。 Ovito Identify diamond structure命令可以识别和统计金刚石结构,但是无法直接输出结构的变化情况。 本文使用python调用ovito包的方法,可以持续统计各步的金刚石结构,具体代码如下: from ovito…...
计算机基础知识解析:从应用到架构的全面拆解
目录 前言 1、 计算机的应用领域:无处不在的数字助手 2、 计算机的进化史:从算盘到量子计算 3、计算机的分类:不止 “台式机和笔记本” 4、计算机的组件:硬件与软件的协同 4.1 硬件:五大核心部件 4.2 软件&#…...
