找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 6590|回复: 18
收起左侧

关于I2C与EEPROM地址的问题

  [复制链接]
ID:538271 发表于 2019-6-23 21:30 | 显示全部楼层 |阅读模式
QQ图片20190623212543.png

AT24c02地址

AT24c02地址

图一 为啥说地址为0x50   1010000  如果原型是0101 0000   那最后一位的读写位不就没有了吗
那如果有读写位  A0~A2都接地 应该 位 0xA0 啊
回复

使用道具 举报

ID:10193 发表于 2019-6-24 07:45 | 显示全部楼层
读地址是0Xa0,写地址是0xa1。
回复

使用道具 举报

ID:401564 发表于 2019-6-24 08:22 | 显示全部楼层
图片上说的是错的,或者是说不严谨,
24C02的读写的地址是:0A0H和0A1H
回复

使用道具 举报

ID:538271 发表于 2019-6-24 10:49 | 显示全部楼层
Y_G_G 发表于 2019-6-24 08:22
图片上说的是错的,或者是说不严谨,
24C02的读写的地址是:0A0H和0A1H

0A0H是什么= =    不应该是0XA0  或者 0XA1吗      关键这个人写程序的时候  用了0X50 还寻到了
回复

使用道具 举报

ID:401564 发表于 2019-6-24 16:56 | 显示全部楼层
我说的是汇编上,你说是C里面,但编译好像是通用的
他的程序应该是在写入的时候是用到了位移了
你看一下输入函数有没有位移的语句
回复

使用道具 举报

ID:401564 发表于 2019-6-24 17:00 | 显示全部楼层
24C02是一个很常用的IIC器件,你随便找一下24C02程序,大多都是0XA0  或者 0XA1的
回复

使用道具 举报

ID:538271 发表于 2019-6-24 21:50 | 显示全部楼层
Y_G_G 发表于 2019-6-24 17:00
24C02是一个很常用的IIC器件,你随便找一下24C02程序,大多都是0XA0  或者 0XA1的

void E2Read(unsigned char *buf, unsigned char addr, unsigned char len)
{
    do {                       //用寻址操作查询当前是否可进行读写操作
        I2CStart();
        if (I2CWrite(0x50<<1)) //应答则跳出循环,非应答则进行下一次查询
        {
            break;
        }
        I2CStop();
    } while(1);
    I2CWrite(addr);            //写入起始地址
    I2CStart();                //发送重复启动信号
    I2CWrite((0x50<<1)|0x01);  //寻址器件,后续为读操作
有左移的  但是我看不懂什么意思  
回复

使用道具 举报

ID:483407 发表于 2019-6-24 21:59 | 显示全部楼层
0xa0或0xa1,前7位为24C02的器件地址(前4位固定为1010,后3位取决于A2、A1、A0三个引脚在电路中的连接),后1位为读写方向。
此图中,把24C02的地址描述为0x50,没毛病。读写位加到后面,0x50要左移1位,就成了0xa0或0xa1。
至于0x50和0x62,是寻到的什么器件,没图,天知道。不过可以确定,决对不是本图中的24C02。
回复

使用道具 举报

ID:418269 发表于 2019-6-25 11:05 | 显示全部楼层
zzh985514474 发表于 2019-6-24 10:49
0A0H是什么= =    不应该是0XA0  或者 0XA1吗      关键这个人写程序的时候  用了0X50 还寻到了

0x50是24c02地址没错,但需要在读写操作时<<1,读地址(0x50<<1),写地址 (0x50<<1|0x01)
回复

使用道具 举报

ID:401564 发表于 2019-6-25 11:28 | 显示全部楼层
zzh985514474 发表于 2019-6-24 21:50
void E2Read(unsigned char *buf, unsigned char addr, unsigned char len)
{
    do {                ...

我就说他有位移的语句了,没见过这么扯的
本来读写24C02就已经要用位移了,生怕位移多了数据可能会对不上号,他可好,生拉硬扯的搞个0X50这玩意出来
回复

使用道具 举报

ID:538271 发表于 2019-6-25 11:55 | 显示全部楼层
wangwing 发表于 2019-6-24 21:59
0xa0或0xa1,前7位为24C02的器件地址(前4位固定为1010,后3位取决于A2、A1、A0三个引脚在电路中的连接), ...

我有完整的程序  但有点长 您介意我单独私聊你不
回复

使用道具 举报

ID:538271 发表于 2019-6-25 15:47 | 显示全部楼层
Y_G_G 发表于 2019-6-25 11:28
我就说他有位移的语句了,没见过这么扯的
本来读写24C02就已经要用位移了,生怕位移多了数据可能会对不 ...

unsigned char I2cSendByte(unsigned char dat)
{
        unsigned char a=0,b=0;//最大255,一个机器周期为1us,最大延时255us。               
        for(a=0;a<8;a++)//要发送8位,从最高位开始
        {
                SDA=dat>>7;         //起始信号之后SCL=0,所以可以直接改变SDA信号
                dat=dat<<1;
                Delay10us();
                SCL=1;
                Delay10us();//建立时间>4.7us
                SCL=0;
                Delay10us();//时间大于4us               
        }

unsigned char I2cReadByte()
        unsigned char a=0,dat=0;
        SDA=1;                        //起始和发送一个字节之后SCL都是0
        Delay10us();
        for(a=0;a<8;a++)//接收8个字节
        {
                SCL=1;
                Delay10us();
                dat<<=1;
                dat|=SDA;
                Delay10us();
                SCL=0;
                Delay10us();


请问这发送的过程是不是 主机发送DAT这个数据 然后通过SDA的数据线给到从机,那这时不用像读取函数那样先给SDA=1吗?
读取函数这个的过程 是不是从机通SDA给到主机数据DATA 那这一步dat<<=1; dat|=SDA;什么意思 将data 0000 0000  变为1111 1111 ?,
回复

使用道具 举报

ID:160500 发表于 2019-6-25 17:08 | 显示全部楼层
地址0x50是没错,你说的那个0xA0、0xA1是加上了读写位的。不是一回事
回复

使用道具 举报

ID:401564 发表于 2019-6-25 17:24 | 显示全部楼层
dat是一个变量,实际上就是一个地址,而SDA是一个位
l是按位或的运算,而不是或运算
按位或运算只会改变相对应该的位,其它位不变的
如果dat=0000 0000,SDA=1,按位或运算之后就是dat=0000 0001
回复

使用道具 举报

ID:571958 发表于 2019-6-25 18:52 | 显示全部楼层
                 SDA=dat>>7;         //起始信号之后SCL=0,所以可以直接改变SDA信号 ,这是发送给slave的。

  那这一步dat<<=1; dat|=SDA  ,这样一般是 数据左一位,SDA上状态读入 dat bit0
  这样做八次刚好得到1 byte数据
回复

使用道具 举报

ID:18297 发表于 2019-6-25 20:11 | 显示全部楼层
这个只是一个认识上的问题。
其实很简单,1)有人把0xa0(读)和0Xa1(写)当作地址,直接发送这两个。
                  2)例外有人把0X50当成地址,但是发送前先左移一位,(0x50<<1+0)=0xa0(读)
                      (0x50<<1+1)=0xa1(写),再发送给EEPROM。
                  看吧,结果都是一样的。
                 只是程序写得不同而已。自己明白就好。到底你给发送的是什么?
                 如果你不移位,只发送0x50,就错了。
回复

使用道具 举报

ID:483407 发表于 2019-6-25 20:51 | 显示全部楼层
我的理解:没有主机,没有从机。这2个函数,从其名字上来理解,前者功能是向某总线上发送一个字节,后者为从总线上读一个字节,如此而已(多好的程序呀,向这段代码的作者致敬)。
建议:如果你要用这个函数,放到自己的程序中能够实现功能,这就够了,不必深究;如果你是学习,就想把这段代码搞明白,那么你要做的有2个,一是把时序整明白,二是。。。。。。。(dat<<=1; dat|=SDA;//dat前移一位,读总线,把结果放在dat的最后一位)
回复

使用道具 举报

ID:307020 发表于 2019-6-26 00:18 | 显示全部楼层
按DataSheet,读为0xA1,写为0xA0;理由是R/W
QQ截图20190626001007.png
回复

使用道具 举报

ID:907706 发表于 2023-7-18 11:45 | 显示全部楼层
认真的去看这些文字,他讲的是24C01的 地址是7位 其中高4位是固定的1010(A2 A1 A0) 我们需要补R/W位(是读写位),补0和补1是你自己决定的  补完后就是 1010 0000
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表