认真的去看这些文字,他讲的是24C01的 地址是7位 其中高4位是固定的1010(A2 A1 A0) 我们需要补R/W位(是读写位),补0和补1是你自己决定的 补完后就是 1010 0000 |
按DataSheet,读为0xA1,写为0xA0;理由是R/W |
QQ截图20190626001007.png (78.84 KB, 下载次数: 56)
我的理解:没有主机,没有从机。这2个函数,从其名字上来理解,前者功能是向某总线上发送一个字节,后者为从总线上读一个字节,如此而已(多好的程序呀,向这段代码的作者致敬)。 建议:如果你要用这个函数,放到自己的程序中能够实现功能,这就够了,不必深究;如果你是学习,就想把这段代码搞明白,那么你要做的有2个,一是把时序整明白,二是。。。。。。。(dat<<=1; dat|=SDA;//dat前移一位,读总线,把结果放在dat的最后一位) |
这个只是一个认识上的问题。 其实很简单,1)有人把0xa0(读)和0Xa1(写)当作地址,直接发送这两个。 2)例外有人把0X50当成地址,但是发送前先左移一位,(0x50<<1+0)=0xa0(读) (0x50<<1+1)=0xa1(写),再发送给EEPROM。 看吧,结果都是一样的。 只是程序写得不同而已。自己明白就好。到底你给发送的是什么? 如果你不移位,只发送0x50,就错了。 |
SDA=dat>>7; //起始信号之后SCL=0,所以可以直接改变SDA信号 ,这是发送给slave的。 那这一步dat<<=1; dat|=SDA ,这样一般是 数据左一位,SDA上状态读入 dat bit0 这样做八次刚好得到1 byte数据 |
dat是一个变量,实际上就是一个地址,而SDA是一个位 l是按位或的运算,而不是或运算 按位或运算只会改变相对应该的位,其它位不变的 如果dat=0000 0000,SDA=1,按位或运算之后就是dat=0000 0001 |
地址0x50是没错,你说的那个0xA0、0xA1是加上了读写位的。不是一回事 |
Y_G_G 发表于 2019-6-25 11:28 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 ?, |
wangwing 发表于 2019-6-24 21:59 我有完整的程序 但有点长 您介意我单独私聊你不 |
zzh985514474 发表于 2019-6-24 21:50 我就说他有位移的语句了,没见过这么扯的 本来读写24C02就已经要用位移了,生怕位移多了数据可能会对不上号,他可好,生拉硬扯的搞个0X50这玩意出来 |
zzh985514474 发表于 2019-6-24 10:49 0x50是24c02地址没错,但需要在读写操作时<<1,读地址(0x50<<1),写地址 (0x50<<1|0x01) |
0xa0或0xa1,前7位为24C02的器件地址(前4位固定为1010,后3位取决于A2、A1、A0三个引脚在电路中的连接),后1位为读写方向。 此图中,把24C02的地址描述为0x50,没毛病。读写位加到后面,0x50要左移1位,就成了0xa0或0xa1。 至于0x50和0x62,是寻到的什么器件,没图,天知道。不过可以确定,决对不是本图中的24C02。 |
Y_G_G 发表于 2019-6-24 17:00 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); //寻址器件,后续为读操作 有左移的 但是我看不懂什么意思 |
24C02是一个很常用的IIC器件,你随便找一下24C02程序,大多都是0XA0 或者 0XA1的 |
我说的是汇编上,你说是C里面,但编译好像是通用的 他的程序应该是在写入的时候是用到了位移了 你看一下输入函数有没有位移的语句 |
Y_G_G 发表于 2019-6-24 08:22 0A0H是什么= = 不应该是0XA0 或者 0XA1吗 关键这个人写程序的时候 用了0X50 还寻到了 |
图片上说的是错的,或者是说不严谨, 24C02的读写的地址是:0A0H和0A1H |
读地址是0Xa0,写地址是0xa1。 |