对I2C总线上挂接多个AT24C02的读写操作


#include <reg51.h>         //  包含51单片机寄存器定义的头文件
#include <intrins.h>       //包含_nop_()函数定义的头文件
#define    OP_READ1    0xa1        // 器件1地址以及读取操作,0xa1即为1010 0001B
#define    OP_WRITE1 0xa0        // 器件1地址以及写入操作,0xa1即为1010 0000B
#define    OP_READ2    0xaf        // 器件2地址以及读取操作,0xa1即为1010 1111B
#define    OP_WRITE2 0xae        // 器件2地址以及写入操作,0xa1即为1010 1110B
sbit SDA=P3^4;             //将串行数据总线SDA位定义在为P3.4引脚
sbit SCL=P3^3;             //将串行时钟总线SDA位定义在为P3.3引脚
/*****************************************************
函数功能:延时1ms
(3j+2)*i=(3×33+2)×10=1010(微秒),可以认为是1毫秒
***************************************************/
void delay1ms()
{
   unsigned char i,j;    
     for(i=0;i<10;i++)
      for(j=0;j<33;j++)
       ;         
 }
/*****************************************************
函数功能:延时若干毫秒
入口参数:n
***************************************************/
 void delaynms(unsigned char n)
 {
   unsigned char i;
    for(i=0;i<n;i++)
       delay1ms();
 }
/***************************************************
函数功能:开始数据传送
***************************************************/
void start()
// 开始位
{
    SDA = 1;    //SDA初始化为高电平“1”
    SCL = 1;    //开始数据传送时,要求SCL为高电平“1”
    _nop_();    //等待一个机器周期
    _nop_();    //等待一个机器周期
    SDA = 0;    //SDA的下降沿被认为是开始信号
    _nop_();    //等待一个机器周期
    _nop_();    //等待一个机器周期
    _nop_();    //等待一个机器周期
    _nop_();    //等待一个机器周期
    SCL = 0;    //SCL为低电平时,SDA上数据才允许变化(即允许以后的数据传递)
    _nop_();    //等待一个机器周期
}
/***************************************************
函数功能:结束数据传送
***************************************************/
void stop()
// 停止位
{
    SDA = 0;     //SDA初始化为低电平“0”
    _nop_();     //等待一个机器周期
    _nop_();     //等待一个机器周期
    SCL = 1;     //结束数据传送时,要求SCL为高电平“1”
    _nop_();     //等待一个机器周期
    _nop_();     //等待一个机器周期
    _nop_();     //等待一个机器周期
    _nop_();     //等待一个机器周期
    _nop_();     //等待一个机器周期
    _nop_();     //等待一个机器周期
    SDA = 1;    //SDA的上升沿被认为是结束信号    
}
/***************************************************
函数功能:从AT24Cxx读取数据
出口参数:x
***************************************************/
unsigned char ReadData()
// 从AT24Cxx移入数据到MCU
{
    unsigned char i;
    unsigned char x;           //储存从AT24Cxx中读出的数据
    for(i = 0; i < 8; i++)
    {
        SCL = 1;                //SCL置为高电平
        x<<=1;                  //将x中的各二进位向左移一位
        x|=(unsigned char)SDA;  //将SDA上的数据通过按位“或“运算存入x中
        SCL = 0;               //在SCL的下降沿读出数据
    }
    return(x);                //将读取的数据返回
}
/***************************************************
函数功能:向AT24Cxx的当前地址写入数据
入口参数:y (储存待写入的数据)
***************************************************/
//在调用此数据写入函数前需首先调用开始函数start(),所以SCL=0
bit WriteCurrent(unsigned char y)
{
    unsigned char i;
    bit ack_bit;               //储存应答位
    for(i = 0; i < 8; i++)        // 循环移入8个位
    {
        SDA = (bit)(y&0x80);   //通过按位“与”运算将最高位数据送到S
                              //因为传送时高位在前,低位在后
        _nop_();              //等待一个机器周期   
       SCL = 1;              //在SCL的上升沿将数据写入AT24Cxx      
       _nop_();              //等待一个机器周期 
      _nop_();               //等待一个机器周期       
        
          SCL = 0;              //将SCL重新置为低电平,以在SCL线形成传送数据所需的8个脉冲
        y <<= 1;              //将y中的各二进位向左移一位
    }
    SDA = 1;              // 发送设备(主机)应在时钟脉冲的高电平期间(SCL=1)释放SDA线,
                    //以让SDA线转由接收设备(AT24Cxx)控制
    _nop_();        //等待一个机器周期 
    _nop_();        //等待一个机器周期 
    SCL = 1;       //根据上述规定,SCL应为高电平
    _nop_();       //等待一个机器周期 
    _nop_();       //等待一个机器周期 
    _nop_();       //等待一个机器周期 
    _nop_();       //等待一个机器周期 
    ack_bit = SDA; //接受设备(AT24Cxx)向SDA送低电平,表示已经接收到一个字节
                   //若送高电平,表示没有接收到,传送异常
    SCL = 0;       //SCL为低电平时,SDA上数据才允许变化(即允许以后的数据传递)
    return  ack_bit;// 返回AT24Cxx应答位
}
/***************************************************
函数功能:向第一个AT24Cxx中的指定地址写入数据
入口参数:add (储存指定的地址);dat(储存待写入的数据)
***************************************************/
void WriteSet1(unsigned char add, unsigned char dat)
// 在指定地址addr处写入数据WriteCurrent
{
    start();                  //开始数据传递
    WriteCurrent(OP_WRITE1);  //选择要操作的第一个AT24Cxx芯片,并告知要对其写入数据
    WriteCurrent(add);        //写入指定地址
    WriteCurrent(dat);        //向当前地址(上面指定的地址)写入数据
    stop();                   //停止数据传递
    delaynms(4);               //1个字节的写入周期为1ms, 最好延时1ms以上
}
/***************************************************
函数功能:向第二个AT24Cxx中的指定地址写入数据
入口参数:add (储存指定的地址);dat(储存待写入的数据)
***************************************************/
void WriteSet2(unsigned char add, unsigned char dat)
// 在指定地址addr处写入数据WriteCurrent
{
    start();                  //开始数据传递
    WriteCurrent(OP_WRITE2);  //选择要操作的AT24Cxx芯片,并告知要对其写入数据
    WriteCurrent(add);        //写入指定地址
    WriteCurrent(dat);        //向当前地址(上面指定的地址)写入数据
    stop();                   //停止数据传递
    delaynms(4);               //1个字节的写入周期为1ms, 最好延时1ms以上
}
/***************************************************
函数功能:从第一个AT24Cxx中的当前地址读取数据
出口参数:x (储存读出的数据) 
***************************************************/
unsigned char ReadCurrent1()
{
    unsigned char x;
    start();                   //开始数据传递
    WriteCurrent(OP_READ1);   //选择要操作的第一个AT24Cxx芯片,并告知要读其数据
    x=ReadData();             //将读取的数据存入x
    stop();                   //停止数据传递
    return x;                 //返回读取的数据
}

/***************************************************
函数功能:从第二个AT24Cxx中的当前地址读取数据
出口参数:x (储存读出的数据) 
***************************************************/
unsigned char ReadCurrent2()
{
    unsigned char x;
    start();                   //开始数据传递
    WriteCurrent(OP_READ2);    //选择要操作的第二个AT24Cxx芯片,并告知要读其数据
    x=ReadData();              //将读取的数据存入x
    stop();                    //停止数据传递
    return x;                  //返回读取的数据
}
/***************************************************
函数功能:从第一个AT24Cxx中的指定地址读取数据
入口参数:set_addr
出口参数:x 
***************************************************/
unsigned char ReadSet1(unsigned char set_addr)
// 在指定地址读取
{
    start();                      //开始数据传递
    WriteCurrent(OP_WRITE1);       //选择要操作的第一个AT24Cxx芯片,并告知要对其写入数据
    WriteCurrent(set_addr);       //写入指定地址
    return(ReadCurrent1());        //从第一个AT24Cxx芯片指定地址读出数据并返回
}
/***************************************************
函数功能:从第二个AT24Cxx中的指定地址读取数据
入口参数:set_addr
出口参数:x 
***************************************************/
unsigned char ReadSet2(unsigned char set_addr)
// 在指定地址读取
{
    start();                       //开始数据传递
    WriteCurrent(OP_WRITE2);       //选择要操作的第二个AT24Cxx芯片,并告知要对其写入数据
    WriteCurrent(set_addr);        //写入指定地址
    return(ReadCurrent2());        //从第二个AT24Cxx芯片指定地址读出数据并返回
}
/***************************************************
函数功能:主函数
***************************************************/
main(void)
{
   unsigned char x;
   SDA = 1;           // SDA=1,SCL=1,使主从设备处于空闲状态
    SCL = 1;             
   WriteSet1(0x36,0xaa);   //将数据"0xaa"写入第一个AT24C02的指定地址"0x36"
    x=ReadSet1(0x36);       //从第二个AT24C02中的指定地址"0x36"读出数据  
   WriteSet2(0x48,x);      //将读出的数据写入第二个AT24C02的指定地址"0x48"?
    P1=ReadSet2(0x48);      //将从第二个AT24C02的指定地址读出的数据送P1口显示验证
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

python文件打包实战技巧

众所周知&#xff0c;python是一种脚本语言&#xff0c;python程序必须在python环境下运行&#xff0c;所以如果想把自己写的程序给别人看的话&#xff0c;就比较麻烦&#xff0c;他需要先配置python环境&#xff0c;对于电脑小白来说这是“要命”的事情。而且如果是客户的话&a…

ubuntu多用户环境dockerbug,卸载重装docker流程

之前不小心误操作删除重装docker&#xff0c;结果删除没成功&#xff0c;更没法重装&#xff0c;每次apt install都会报一个docker错误&#xff0c;虽然不影响软件的常规安装&#xff5e;但是现在还是需要装一个完整docker&#xff0c;还是选择删除一下&#xff0c;重点是关闭服…

多环境及SpringBoot项目部署

1、多环境 2、项目部署上线 原始前端 / 后端项目宝塔Linux容器容器平台 3、前后端联调 4、项目扩展和规划 多环境 程序员鱼皮-参考文章 本地开发&#xff1a;localhost&#xff08;127.0.0.1&#xff09; 多环境&#xff1a;指同一套项目代码在把不同的阶段需要根据实际…

共享单车之数据可视化

文章目录 第1关&#xff1a;绘制地图第2关&#xff1a;绘制流量最高的五条线路的路程图 第1关&#xff1a;绘制地图 任务描述 本关任务&#xff1a;使用JSP在百度地图上绘制一条共享单车起始路程。 相关知识 为了完成本关任务&#xff0c;你需要掌握&#xff1a; 如何创建地…

macos下转换.dmg文件为 .iso .cdr文件的简单方法

为了让镜像文件在mac 和windows平台通用, 所以需要将.dmg格式的镜像文件转换为.iso文件, 转换方法也非常简单, 一行命令即可 hdiutil convert /path/to/example.dmg -format UDTO -o /path/to/example.iso 转换完成后的文件名称默认是 example.iso.cdr 这里直接将.cdr后缀删…

web一些实验代码—— JavaBean与EL标签

实验9&#xff1a; JavaBean与EL标签 使用javaBean和EL&#xff0c;完成注册和注册信息显示。 1、新建RegisterBean&#xff1b; package com.example.weeebbbb.the10;public class RegisterBean {private String user;private String pass;private String repass;private S…

【Transformer】深入理解Transformer模型2——深入认识理解(上)

前言 Transformer模型出自论文&#xff1a;《Attention is All You Need》 2017年 近年来&#xff0c;在自然语言处理领域和图像处理领域&#xff0c;Transformer模型都受到了极为广泛的关注&#xff0c;很多模型中都用到了Transformer或者是Transformer模型的变体&#xff0…

OCR在审核应用落地

本文字数&#xff1a;6686字 预计阅读时间&#xff1a;35分钟 01 背景 1、业务背景 在传统视频审核场景中&#xff0c;审核人员需要对进审视频中的文字内容进行逐一审核&#xff0c;避免在文字上出现敏感词、违禁词或者广告等相关词汇。这种人工审核费时费力&#xff0c;并且由…

【数据结构】双向带头循环链表的实现

前言&#xff1a;在前面我们学习了顺序表、单向链表&#xff0c;今天我们在单链表的基础上进一步来模拟实现一个带头双向链表。 &#x1f496; 博主CSDN主页:卫卫卫的个人主页 &#x1f49e; &#x1f449; 专栏分类:数据结构 &#x1f448; &#x1f4af;代码仓库:卫卫周大胖的…

50. Pow(x, n)(Leetcode) C++递归实现(超详细)

文章目录 前言一、题目分析二、算法原理1.递归分析2.递归实现 三、代码实现复杂度分析总结 前言 在本文章中&#xff0c;我们将要详细介绍一下Leetcode中第50题&#xff0c; Pow(x, n)的内容 一、题目分析 题目要求很简单&#xff1a;我们模拟实现一个pow函数。 二、算法原理…

IP地址的四大类型:动态IP、固定IP、实体IP、虚拟IP的区别与应用

在网络通信中&#xff0c;IP地址是设备在互联网上唯一标识的关键元素。动态IP、固定IP、实体IP和虚拟IP是四种不同类型的IP地址&#xff0c;它们各自具有独特的特点和应用场景。 1. 动态IP地址&#xff1a; 动态IP地址是由Internet Service Provider&#xff08;ISP&#xff…

JavaScript使用教程(二):类型、值和变量

计算机程序通过操作值&#xff08;如数值3.14&#xff09;或文本&#xff08;如“Hello World”&#xff09;来工作。编程语言中这些可以表示和操作的值被称为类型&#xff0c;而一门语言支持的类型集也是这门语言最基本的特征。程序在需要把某个值保存下来以便将来使用时&…

Halcon纹理分析texture_laws/trans_from_rgb

Halcon纹理分析 文章目录 Halcon纹理分析1. 纹理滤波器2. 织物折痕检测 纹理是图像表面的一种灰度变化。有的纹理很规则&#xff0c;会以局部小区域为单元重复出现&#xff0c;而有的纹理则呈现出随机性。对于规则的纹理&#xff0c;可以很容易地从中分辨出重复的区域&#xff…

Unity坦克大战开发全流程——开始场景——开始界面

开始场景——开始界面 step1&#xff1a;设置UI 反正按照这张图拼就行了 step2&#xff1a;写脚本 前面的拼UI都是些比较机械化的工作&#xff0c;直到这里写代码的时候才真正开始有点意思了&#xff0c;从这里开始&#xff0c;我们就要利用面向对象的思路来进行分析&#xff1…

基于Java图书借阅管理系统设计与实现(源码+部署文档)

博主介绍&#xff1a; ✌至今服务客户已经1000、专注于Java技术领域、项目定制、技术答疑、开发工具、毕业项目实战 ✌ &#x1f345; 文末获取源码联系 &#x1f345; &#x1f447;&#x1f3fb; 精彩专栏 推荐订阅 &#x1f447;&#x1f3fb; 不然下次找不到 Java项目精品实…

这儿有一道SPSS回归分析考试题,大家学会了吗?

为研究某地区房地产市场的价格与相关影响因素之间的关系&#xff0c;现从该地区采集了 20 份样本&#xff0c;数据如下表&#xff0c;请给出销售价格与相关影响因素之间的函数表达式&#xff0c;并从统计学角度分析这些因素之间的关系&#xff0c;最后预测 X 小区的平均销售价格…

集群部署篇--Redis 主从模式

文章目录 前言Redis 主从部署&#xff1a;1.1 主从架构 介绍&#xff1a;1.2 主从架构 实现&#xff1a;1.2.1 redis 安装&#xff1a; 1.3 主从架构优缺点&#xff1a;1.4 故障转移&#xff1a; 总结 前言 显然在线上环境中 Redis 服务不能以单机的方式运行&#xff0c;必须有…

基于Java学生成绩管理系统设计与实现(源码+部署文档+报告)

博主介绍&#xff1a; ✌至今服务客户已经1000、专注于Java技术领域、项目定制、技术答疑、开发工具、毕业项目实战 ✌ &#x1f345; 文末获取源码联系 &#x1f345; &#x1f447;&#x1f3fb; 精彩专栏 推荐订阅 &#x1f447;&#x1f3fb; 不然下次找不到 Java项目精品实…

Python-地图可视化

地图可视化 1.基础地图使用1.1基础地图演示1.2视觉映射器 2.全国疫情地图2.1数据整理2.2创建地图并添加数据2.3设置全局配置 3.省级疫情图 1.基础地图使用 1.1基础地图演示 # 导入模块 from pyecharts.charts import Map # 绘图 map Map() # 构建数据 data [("北京市&…

hyperf console 执行

一、原理描述 hyperf中&#xff0c;不难发现比如自定义控制器中获取参数&#xff0c;hyperf.php中容器获取&#xff0c;传入的都是接口&#xff0c;而不是实体类。 这是因为框架中的配置文件有设置对应抽象类的子类&#xff0c;框架加载的时候将其作为数组&#xff0c;使用的…