历遍单片机下的IIC设备[ESP--0]

IIC是常见的通讯协议,传输速度一般在100KB,很多的电子部件都是使用这个协议传输,了解它大有用处
简单来说,IIC只用两根线就能控制多个设备,相当简单好用

IIC使用的线分别为 SCL (serial clock 串行时钟线)和 SDA (serial data 串行数据线)

IIC的模式和地址

你可能会说,哎呀,这看上去也太难了,这让我怎么连线啊。没关系,打开你的单片机开发板引脚图,找到你支持IIC接口的那个GPIO,直接把SCL和SDA 怼到原件对应的引脚上就行了,然后使用封装好的库wire.h 引用个函数就配置好了(质疑PYTHON,理解PYTHON,成为PYTHON)

可以看到,ESP支持IIC ,GPIO21 和 GPIO 22分别是SDA和 SCL

地址问题

显然,一根IIC总线下可以接多个设备,为了通讯,每个设备都有自己的地址 (一般都被烧写进硬件中),标准的IIC设备是7位地址

下图A[6:0]是地址位,后面是读写位,所以理论上一根总线下,最多2^8=128个(设备范围是从0x010x7F),但是有些特殊地址是另作他用的,下面列出几个常用地址

使用IIC进行简单通信
  • #include <Wire.h> 要使用IIC的库 Wire.h
  • Wire.begin(); 使用前要初始化IIC总线(下面有解释)
  • Wire.beginTransmission(0x5A); 输入地址,向从机发信号
  • Wire.write(0x01); 向已经输入的地址发信
  • byte error = Wire.endTransmission();结束当前通信并获得通信状态 0 为成功的状态
CPP 复制代码
#include <Wire.h>
#include <Arduino.h>
//不载入Arduino.h,好像无法识别Serial  byte这个名字


void setup() {
  Wire.begin(); // 初始化 I2C 总线
  Serial.begin(9600);

  // 开始向地址为 0x5A 的 I2C 设备发送数据
  Wire.beginTransmission(0x5A);
  Wire.write(0x01);  // 写入数据
  Wire.write(0x02);  // 写入数据
  Wire.write(0x03);  // 写入数据
  byte error = Wire.endTransmission();  // 结束传输,并获取错误代码

  if (error == 0) {
    Serial.println("Data sent successfully!");
  } else {
    Serial.print("Failed to send data, error code: ");
    Serial.println(error);
  }
}

void loop() {
  // 循环代码
}

注意,这个程序仅仅做示例只用,你的设备地址不一定是5A,写入也可能没有用

Wire.begin();这个函数过程中发生了什么?

  1. 初始化 I2C 总线硬件

Wire.begin() 首先会初始化与 I2C 通信相关的硬件资源。这包括设置 I2C 控制器的时钟频率(通常为 100 kHz 或 400 kHz)、配置 SDA(数据线)和 SCL(时钟线)引脚的功能。没错,在ESP上就是配置GPIO21和GPIO22为IIC通信口

  1. 配置 I2C 控制器

I2C 控制器需要在开始通信之前进行配置。Wire.begin() 会设置控制器的模式(主机或从机),并配置相关的寄存器。

  • 主机模式 :当 Wire.begin() 没有参数时,Arduino 作为主机初始化 I2C 总线。
  • 从机模式 :当 Wire.begin(address) 带有参数时,Arduino 作为从机初始化 I2C 总线,并设置从机地址。
  1. 启动 I2C 总线

在初始化完成后,Wire.begin() 会启动 I2C 总线,使 Arduino 能够开始与其他设备进行通信。这包括设置起始条件(Start Condition),告诉其他设备准备开始通信。

  1. 清除总线状态

初始化过程中,Wire.begin() 还会清除任何可能存在的总线错误状态,确保总线处于干净、可通信的状态。

扫描IIC下的设备
  • 标准IIC的从机地址标号是7位,除去0号地址,总共是127个,挨个尝试呼叫即可
  • 在呼叫前,应该正确初始化IIC设备,否则没有应答是常态
  • 楼主这里用的是VL53L0X这个设备(距离传感器)

先CODE一下

CPP 复制代码
#include <Wire.h>
#include <Arduino.h>

void setup() {
  Wire.begin(); // 初始化 I2C 总线
  Serial.begin(9600);


  byte error;
  for (byte address = 1; address < 127; address++) {
    Wire.beginTransmission(address); // 使用循环中的address变量
    error = Wire.endTransmission(); // 结束传输,并获取错误代码

    if (error == 0) {
      Serial.print("address:");
      Serial.print(address, HEX);
      Serial.println("     Data sent successfully!");
    } else {
      Serial.print("Failed to send data to address ");
       Serial.print(address, HEX);
      Serial.print(", error code: ");
      Serial.println(error);
    }
  }
}

void loop() {

}

看看运行效果

bash 复制代码
Failed to send data to address , error code: 2
Failed to send data to address , error code: 2
Failed to send data to address , error code: 2
Failed to send data to address , error code: 2
Failed to send data to address , error code: 2
Failed to send data to address , error code: 2
Failed to send data to address , error code: 2

我去,怎么全部失败了?哦,我没有正确的启动IIC设备

cpp 复制代码
#include <Wire.h>
#include <Arduino.h>
#include <Adafruit_VL53L0X.h>

Adafruit_VL53L0X lox = Adafruit_VL53L0X();

// 定义 XSHUT 引脚
#define XSHUT_PIN 2
//如果你不希望使用GPIO 直接把它悬空,或者接地即可



void setup() {
  Wire.begin(); // 初始化 I2C 总线
  Serial.begin(9600);

  //要正确的初始化IIC设备,否则是检测不到的
    // 初始化 XSHUT 引脚为输出
  pinMode(XSHUT_PIN, OUTPUT);
  digitalWrite(XSHUT_PIN, LOW); // 初始状态为低电平

  // 启用传感器
  digitalWrite(XSHUT_PIN, HIGH);
  if (!lox.begin()) {
    Serial.println(F("Failed to boot VL53L0X"));
    while(1);
  }

  byte error;
  for (byte address = 1; address < 127; address++) {
    Wire.beginTransmission(address); // 使用循环中的address变量
    error = Wire.endTransmission(); // 结束传输,并获取错误代码

    if (error == 0) {
      Serial.print("address:");
      Serial.print(address, HEX);
      Serial.println("     Data sent successfully!");
    } else {
      Serial.print("Failed to send data to address ");
       Serial.print(address, HEX);
      Serial.print(", error code: ");
      Serial.println(error);
    }
  }
}

void loop() {
  // 循环代码(如果需要)
}
bash 复制代码
Failed to send data to address 28, error code: 2
address:29     Data sent successfully!
Failed to send data to address 2A, error code: 2
Failed to send data to address 2B, error code: 2
Failed to send data to address 2C, error code: 2

现在果然成功了,扫描到0x29 处有这个设备

相关推荐
m0_7482540923 分钟前
STM32--超声波模块(HC—SR04)(标准库+HAL库)
stm32·单片机·嵌入式硬件
南城花随雪。32 分钟前
单片机:实现FFT快速傅里叶变换算法(附带源码)
单片机·嵌入式硬件·算法
逝灮1 小时前
【蓝桥杯——物联网设计与开发】基础模块8 - RTC
stm32·单片机·嵌入式硬件·mcu·物联网·蓝桥杯·rtc
LXL_241 小时前
模拟——郑益慧_笔记1_绪论
嵌入式硬件
weixin_452600697 小时前
串行时钟保持芯片D1380/D1381,低功耗工作方式自带秒、分、时、日、日期、月、年的串行时钟保持芯片,每个月多少天以及闰年能自动调节
科技·单片机·嵌入式硬件·时钟·白色家电电源·微机串行时钟
森旺电子10 小时前
51单片机仿真摇号抽奖机源程序 12864液晶显示
单片机·嵌入式硬件·51单片机
不过四级不改名67712 小时前
蓝桥杯嵌入式备赛教程(1、led,2、lcd,3、key)
stm32·嵌入式硬件·蓝桥杯
小A15913 小时前
STM32完全学习——SPI接口的FLASH(DMA模式)
stm32·嵌入式硬件·学习
Rorsion13 小时前
各种电机原理介绍
单片机·嵌入式硬件
善 .16 小时前
单片机的内存是指RAM还是ROM
单片机·嵌入式硬件