数码之家

 找回密码
 立即注册
搜索
查看: 1241|回复: 8

[Arduino] 学习使用ESP8266(2)-- Arduino的 IIC总线地址是7位的!

[复制链接]
发表于 2022-9-18 12:05:17 | 显示全部楼层 |阅读模式

爱科技、爱创意、爱折腾、爱极致,我们都是技术控

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 广东梁百万 于 2022-9-18 16:37 编辑

这几天学习使用Arduino的 IIC总线,在ESP8266开发板焊上24c04 存储器, 用例程改了从机地址下载测试,不能通过,反复多次修改都不行,手上买了ESP32开发板,换上ESP32板上也不行,

(话说我对IIC总线的数据格式还是略懂一点)。
接上 简易逻辑分析仪, 发现 开发板发出的地址数据竟然是 向左移了一位,  比如发送 24c02的地址是 10100000(0xa0),  用逻辑分析仪看到是 01000000,  左边那位丢失了,右边多了一个0。

又重新下载不同版本的SDK包,又装了Arduino 2.0 , 都是一样结果---地址发送有问题,测试不成功。
............
............


昨晚搜索到关于 Arduino的 IIC总线  24C02实例 , 终于明白怎么回事------Arduino的 IIC总线 地址 是7位的, 要把常规的8位地址除以2, 也就是 0xa0 要换成  0x50 ( 人为 右移一位) 。
今日上午按他例程测试,  终于成功了。   

总结 :  Arduino的 IIC总线 地址 是7位的 ,  常规8位地址值 要除以2 才能在Arduino上使用。其他数据值没影响。



微信图片_20220918120146.jpg

打赏

参与人数 2家元 +72 收起 理由
ww5223017240 + 20 謝謝分享
家睦 + 52

查看全部打赏

发表于 2022-9-18 15:46:44 | 显示全部楼层
严谨来说,就是7位地址或10位地址。使用7位地址时,放在设备地址字节的第1~第7位,第0位是读写位。有时,我们习惯把它们作为一体看待,如把设备地址=0x50说成地址=0xA0,这是不严谨的说法。

可具体可以看这篇文章
https://blog.csdn.net/geju323/article/details/119787270


回复 支持 2 反对 0

使用道具 举报

发表于 2022-9-18 17:29:41 | 显示全部楼层
https://blog.csdn.net/geju323/article/details/119787270    IIC用来接传感器OLED就行了,自带flash, 没必要外接EEPROM
回复 支持 反对

使用道具 举报

发表于 2022-9-18 18:04:29 | 显示全部楼层
二楼正解
也可以说成是两个地址,一个是读出地址,一个是写入地址,其实就是7位地址加了读写指令
回复 支持 1 反对 0

使用道具 举报

发表于 2022-9-18 20:16:35 | 显示全部楼层
2楼解释的很详细,其实我们常用语的I2C地址基本上都是7位的,然后加一位读写标志,就形成了所谓的8位地址,所以8位地址的说法是不严谨的。
回复 支持 2 反对 0

使用道具 举报

发表于 2022-9-19 05:51:39 | 显示全部楼层
原来自己写IIC驱动时,都是定义两个地址,一个是读一个是写,这样只是一种习惯,实际上它的地址范围是7位的。刚开始使用现成的MicroPython读写IIC器件时也犯过楼主的错误
回复 支持 反对

使用道具 举报

发表于 2022-9-19 17:28:09 | 显示全部楼层
我也是稀里糊涂弄了很多I2C元件,直到读AHT25传感器的数据手册时才真正了解了器件地址为7位的定义,就是这一句:“在启动传输后, 随后传输的I2C首字节包括7位的I2C设备地址0x38和一个SDA方向位x(读R: ‘ 1', 写W:‘ 0’ )”
回复 支持 反对

使用道具 举报

发表于 2022-9-28 21:31:27 | 显示全部楼层
能费分享下程序么?也在用ESP8266调24C04 试了好几个程序,读出都不成功
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-9-29 09:06:40 来自手机浏览器 | 显示全部楼层
本帖最后由 广东梁百万 于 2022-9-29 20:15 编辑
zhigao1986 发表于 2022-9-28 21:31
能费分享下程序么?也在用ESP8266调24C04 试了好几个程序,读出都不成功

从24c02读出的数据话data_buf数组上,需要写入的数据放在data_wr数组上。



  1. #include <Wire.h>     //加载iic的库
  2. #define LED1         2    //LED指示灯
  3. #define SDA_PIN 4                           // SDA引脚,默认gpio4(D2)
  4. #define SCL_PIN 5                           // SCL引脚,默认gpio5(D1)

  5. byte data_buf[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};  //读出AT24C02用
  6. byte data_wr[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; //写入AT24C02用




  7. byte IIC_ADDR = 0x50;              // AT24C02的7为IIC器件地址0x50

  8. void setup() {
  9.   Wire.begin(SDA_PIN, SCL_PIN);   //初始化IIC接口,不写入地址则默认为主设备

  10.   pinMode(LED1, OUTPUT);    //LED指示灯

  11. }

  12. void loop() {
  13.      IIC_ADDR= 0X50;  //AT24C02的器件地址
  14.     IIC_read(16, 0x00); //读出 AT24C02的数据,这里的16是读出16字节,0x00是AT24C02的数据起始地址

  15. }








  16. //-----------------------------------------------------------------------

  17. //多字节  IIC读出
  18. //  IIC读出程序       i读出字节个数 ,ReadAdd读出位置地始地址
  19. uint8_t IIC_read(byte i, uint8_t ReadAddr)   //i是读出的字节个数  ReadAdd读出位置地始地址
  20. {
  21.    uint8_t j=0;
  22.   uint8_t t = 20;   //超时次数
  23.   uint8_t ret = 0;   //返回正确或错信息  0是正确,非0是错误
  24.     Wire.beginTransmission(IIC_ADDR);  /* 1. 开始一次传输,设置I2C器件地址 */
  25. //---------
  26.   Wire.write(ReadAddr);   /* 2. 需要读出的位置 */
  27. //----------------
  28.   ret = Wire.endTransmission(false);  /* 3. 完成一次I2C通信,发送一个开始位(即重发码)  //返回是0 成功, 1是错误*/
  29. //--------
  30.   Wire.requestFrom(IIC_ADDR, i);  /* 4. 开始一次读取,设置I2C器件地址,读取AT24C02一个字节 */
  31.   //------------
  32.     while (!Wire.available()) /* 5. 读出AT24C02返回的值,成功读取后写入缓存变量处,读取失败返回失败码 */
  33.   {
  34.     t--;      //超时次数
  35.     delay(1);
  36.     if(t == 0)
  37.     {
  38.       return 1;   //出错返回1
  39.     }
  40.   }

  41.    while(i)  
  42. {   
  43.     data_buf[j]= Wire.read();
  44.     i--;
  45.     j++;
  46. }
  47. Wire.endTransmission(true);    // stop transmitting---停止传送
  48. }







  49. //-----------------------------------------------------------------

  50. //多字节  IIC写入
  51. uint8_t IIC_write(uint8_t i, uint8_t WriteAddr)   //uint8_t i 写入的字节数,  
  52. {                                                    //uint8_t WriteAddr起始地址
  53.   byte j=0;
  54.   Wire.beginTransmission(IIC_ADDR);   /* 1. 开始一次传输,设置I2C器件地址 */
  55. //-----------
  56.   Wire.write(WriteAddr);  /* 2. 需要写入的起始位置 */
  57. //-----------

  58. while(i)
  59.   {
  60.   Wire.write(data_wr[j]);   // 3. 需要写入的值
  61.   i--;
  62. j++;
  63. }

  64. //-----------
  65.   return Wire.endTransmission();   /* 4. 完成一次I2C通信,默认发送一个停止位 */
  66. }
复制代码


回复 支持 反对

使用道具 举报

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

本版积分规则

APP|手机版|小黑屋|关于我们|联系我们|法律条款|技术知识分享平台

闽公网安备35020502000485号

闽ICP备2021002735号-2

GMT+8, 2024-4-20 16:52 , Processed in 0.280801 second(s), 14 queries , Redis On.

Powered by Discuz!

© 2006-2023 smzj.net

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