历遍单片机下的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 处有这个设备

相关推荐
典则8 分钟前
STM32FreeRtos入门(四)——任务状态和调度
stm32·单片机·嵌入式硬件
充哥单片机设计14 分钟前
【STM32项目开源】基于STM32的智能天然气火灾监控
stm32·单片机·嵌入式硬件
充哥单片机设计17 分钟前
【STM32项目开源】基于STM32的智能仓库火灾检测系统
stm32·单片机·嵌入式硬件
A9better3 小时前
嵌入式开发学习日志38——stm32之看门狗
stm32·嵌入式硬件·学习
小莞尔3 小时前
【51单片机】【protues仿真】基于51单片机智能路灯控制系统
c语言·stm32·单片机·嵌入式硬件·51单片机
A9better13 小时前
嵌入式开发学习日志36——stm32之USART串口通信前述
stm32·单片机·嵌入式硬件·学习
思诺学长13 小时前
BMS(电池管理系统)的主要功能和架构简述
单片机·嵌入式硬件
czhaii13 小时前
全局不关总中断的 RTOS / CosyOS-II for STCAI MCU
单片机
qq_4017004114 小时前
STM32低功耗Tickless模式
stm32·单片机
点灯小铭16 小时前
基于单片机的自动存包柜设计
数据库·单片机·mongodb·毕业设计·课程设计