AT24C02详解读写地址位


如果光看AT24C02的文档,很抽象,难弄懂。结合程序和实际通讯波形;来描述。

  • 购买回来默认是接GND的,所以安装上AT24C02芯片后地址就是:0xA0

示例程序(写入一个字符为例来展开讲解)

/** Wire库I2C基本读写程序* AT24C02读写操作*
*/#include <Wire.h>                           // 使用Wire库,需要包含头文件
const int16_t I2C_ADDR = 0x50;              // AT24C02的IIC器件地址0x50,这个地址可以通过I2C扫描程序搜索到。
#define button 7bool buttonState = true;
/* 描述:AT24C02写入一个字节函数* 参数:date_wr:    要写入的值*      WriteAddr:  要写入的地址* 返回值:通信成功:0 *        通信失败:1->数据溢出   2->发送addtess时从机接受到NACK *                3->发送数据时接受到NACK  4->其他错误*/
uint8_t at24c02_write(char data_wr, uint8_t WriteAddr)
{/* 1. 开始一次传输,设置I2C器件地址 */Wire.beginTransmission(I2C_ADDR);/* 2. 需要写入的位置 */Wire.write(WriteAddr);/* 3. 需要写入的值 */Wire.write(data_wr);/* 4. 完成一次I2C通信,默认发送一个停止位 */return Wire.endTransmission();
}
/* 描述:AT24C02读取一个字节函数* 参数:date_wr:    要读出值的存放指针*      WriteAddr:  要读出的地址* 返回值:通信成功:0  *        通信失败:1->数据溢出   2->发送address时从机接受到NACK *                3->发送数据时接受到NACK  4->未接受到数据  5->其他*/
uint8_t at24c02_read(char *data_wr, uint8_t ReadAddr)
{uint8_t t = 200;uint8_t ret = 0;/* 1. 开始一次传输,设置I2C器件地址 */Wire.beginTransmission(I2C_ADDR);/* 2. 需要读出的位置 */Wire.write(ReadAddr);/* 3. 完成一次I2C通信,发送一个开始位(即重发码) */ret = Wire.endTransmission(false);/* 4. 开始一次读取,设置I2C器件地址,读取AT24C02一个字节 */Wire.requestFrom(I2C_ADDR, 1);/* 5. 读出AT24C02返回的值,成功读取后写入缓存变量处,读取失败返回失败码 */while (!Wire.available()) {t--;delay(1); if(t == 0){return 1;}}*data_wr= Wire.read(); // receive a byte as characterreturn ret;
}void setup() {/* 初始化串口波特率为115200 */Serial.begin(115200); digitalWrite(LED_BUILTIN, LOW);//板子led,作为观察数据发射状态pinMode(button,INPUT);digitalWrite(button,HIGH);/* 初始化IIC接口,不写入地址则默认为主设备 */  Wire.begin();
}void loop() {buttonState = digitalRead(button);if(buttonState == LOW){delay(250);if(buttonState == LOW){char str0 = 'H';uint8_t Write = at24c02_write(str0, 0);Serial.println("Trigger!!!");Serial.println(Write);digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));delay(2000);
//      char*str2;
//     uint8_t Read = at24c02_read(str2,0);
//      Serial.println(*str2);Serial.println(Read);}    }
}

IIC通讯讲解

要想硬件之间建立通讯,需要知道对方的地址。

就像打电话,打电话前,你必须知道对方的电话号码才行。

  • 确定访问AT24C02的硬件地址(AT24C02手册)

代码上面定义AT24C02的硬件信息填写:

const int16_t I2C_ADDR = 0x50;// AT24C02的IIC器件地址0x50,这个地址可以通过

为什么是0x50的16进制这个地址而不是1010 0000的16进制0xA0呢?
解析:如果CPU读设备,那么读设备地址 = 设备地址 <<1.所以,0x50左移移位就变成了0xA01

  • 源码函数

C:\Users\Administrator\AppData\Local\Arduino15\packages\arduino\hardware\avr\1.8.3\libraries\Wire\src\utility

void twi_setAddress(uint8_t address)
{// set twi slave address (skip over TWGCE bit)TWAR = address << 1;
}
  • 原理图1,将A2,A1,A0都接GND,那么自定义的地址位就都是000,加上第八位确定读写位,如果是读就是1,写就是0,本实例演示的是写数据,那就是确定要写,那么就是0,所以地址就是1010 0000,转换为16进制就是0xA0
  • 示波器捕获到单片机和AT24C02通讯时的波形,紫色代表SDA,黄色代表SCL

    对应代码:
  /* 1. 开始一次传输,设置I2C器件地址 */Wire.beginTransmission(I2C_ADDR);
  • 如果你想挂载8个AT24C02器件,可以根据以下来连接,各器件IIC地址:0x50 - 0x57

下面的AT24C02的地址,只适用于Arduino 平台开发时使用,才对应的上,移位底层函数在封装的时候,会将这个地址左移移一位,具体看上面的原函数,这一点刚刚开始也让我很困惑,当查看原函数的时候,才发现原因。

  • 根据A2,A1,A0,不同的组合,我们可以确定一条总线上可以挂载多少个AT24C02,从而不会导致地址重复或者冲突。最多挂载8个:

    有道翻译:
设备/页地址(A2、A1和A0): A2、A1和A0引脚是设备地址输入
它们是AT24C02的硬线。8个2K设备可以在一个总线系统上寻址
(设备寻址将在设备寻址部分详细讨论)。
AT24C04使用A2和A1输入进行硬线寻址,总共有4个4K设备
在一个单一的总线系统上被处理。A0引脚是无连接的,可以连接到GND。
AT24C08只使用A2输入进行硬线寻址,总共有两个8K设备
在一个单一的总线系统上寻址。A0和A1引脚没有连接,可以连接
GND。
AT24C16不使用设备地址引脚,这限制了总线上单个设备的数量
。A0、A1和A2引脚没有连接,可以连接到地。

第二阶段,写数据地址位。

就比如送快递,将物品送入到某个小区单元还不够,你还要知道具体到,某个单元里的某一栋的门牌号,也就是具体到存储的地址位。

  /* 2. 需要写入的位置 */Wire.write(WriteAddr);

第三阶段,将具体的数据写入到地址位中去,才算完成。

  Wire.write(data_wr);/* 4. 完成一次I2C通信,默认发送一个停止位 */

Arduino AT24C02详解读写地址位相关推荐

  1. arduino i2c 如何写16位寄存器_基于STM32使用I2C读取传感器数据

    撑腰会儿:I2C通信协议介绍​zhuanlan.zhihu.com 上文介绍了I2C协议的基本结构,今天,使用STM32和LM75A温度传感器来实现I2C读取信息. 首先,为了使用I2C读取传感器测量 ...

  2. AT24C02详解(蓝桥杯单片机模块(IIC总线))

    文章目录 特性 描述 引脚描述: 存储组织: 设备操作(IIC) 设备地址 写操作 字节写: 页写入: 确认轮询: 读操作 确认轮询: 当前地址读取: 任意地址读: 连续顺序读: 蓝桥杯部分 特性 2 ...

  3. 详解IP地址后面斜杠加具体数字

    转:详解IP地址后面斜杠加具体数字 详解IP地址后面斜杠加具体数字 如:xx.xx.xx.2/24        xx.xx.xx.0/24 hzhsan:通俗一点就是,斜杠后面的数字就表示子网掩码, ...

  4. 71张图详解IP地址、IP 路由、三层转发、ARP、ICMP

    71张图详解IP地址.IP 路由.三层转发.ARP.ICMP 架构师之道2021-04-07 13:51:24 https://www.toutiao.com/i6948285918986027531 ...

  5. ModBus常用功能码和PLC地址位对应关系,踩坑

    功能码 描述 PLC地址位 寄存器地址位 位/字操作 操作数量 01H 读线圈寄存器 00001-09999 0000H-FFFFH 位操作 单个或多个 02H 读离散输入寄存器 10001-1999 ...

  6. arduino用时钟中断方式的4位数码管动态显示

    一般我们在arduino开发板上显示数字,通常采用多位数码管进行显示,而多位数码管实际是采用"动态扫描显示"的方法进行显示,即依次显示第1位数码管.第2位数码管.第3位数码管.第4 ...

  7. JavaScript:将输入的一串数字转换成中文大写,最高可写12位(千亿)

    将输入的一串数字转换成中文大写,最高可写12位(千亿) 例:输入:10000,输出:壹万 输入:10010,输出:壹万零壹拾 源码: function toChineseBig(num) {// 将接 ...

  8. 易语言写64位魔兽世界游戏 寻路call 教程

    自从Game-EC 8.5.3 辅助模块 发布 开发 64位游戏内存,封包的功能后, 受到了很多写 64位游戏封包,内存辅助的爱好者喜爱 今天在新版本 Game-EC 里面 开发了一个 能调用64位游 ...

  9. 64位计算机连接网络打印机驱动程序,写 64 位打印机驱动程序

    写 64 位打印机驱动程序 08/25/2020 本文内容 如果你编写的是64位驱动程序或编写可编译为在32位和64位系统上运行的驱动程序,请遵循将 驱动程序移植到64位 Windows中的64位移植 ...

  10. 邮箱格式怎么写地址,个人企业电子邮箱怎么注册申请,电子邮箱格式是什么?

    有的人在第一次使用邮箱时,会遇到一个常见的问题:邮箱格式怎么写地址呢?其实,电子邮箱的格式都是有规律的,掌握好这个规律,无论是邮箱注册,还是给其他人写邮件,都会更加方便.那么,个人企业电子邮箱该怎么注 ...

最新文章

  1. 第3章 View的事件体系
  2. jQuery插件开发(一):jQuery类方法
  3. MySQL设计之三范式
  4. hibernate jar包_源码分析 | 咋嘞?你的IDEA过期了吧!加个Jar包就破解了为什么?
  5. Introspector内省和反射的区别.
  6. java h5 上拉加载更多_移动端H5页面上拉加载更多功能实现(二)
  7. 顺便抹了下眼眶的飞鸽传书官方网站
  8. vue js 和原生app调用回调方法问题
  9. 能量采集(HYSBZ-2005)
  10. uva10256 凸包
  11. date oracle 表中_oracle数据库 中to_number()、to_char()、to_date()用法介绍
  12. Ubuntu中Unable to acquire the dpkg frontend lock (/var/lib/dpkg/lock-frontend)问题的解决
  13. JavaScript - 初识
  14. linux 防火墙安装在哪,Linux下Shorewall防火墙安装和配置
  15. Mac版Permute 3(万能视频转换器)
  16. 分位数回归(Stata)
  17. 网络安全:IP地址定位方式
  18. 案例——蚂蚁金服初探,唯一的金融互联网生态
  19. 基于GMap.NET库实现的Windows桌面地图工具软件分享
  20. 微服务网关Gateway基本知识(一)

热门文章

  1. 爬取三个acm网站题库(neuqoj pku hdu)
  2. matlab验证dtft移位性质,7.DTFT的Matlab实现.ppt
  3. fullavatareditor 富头像上传编辑器
  4. 使用模板文件流形式导出文件破损或xxx中的部分内容有问题。解决
  5. linux网络串口工具下载,串口调试工具手机版下载
  6. Visual Studio 2012下载资源 百度云
  7. 华为HCIE云计算培训笔记第一天
  8. xampp的安装教程
  9. 【docker】如何在docker中执行redis命令
  10. 前端学习 JavaScript基础