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

相关推荐
时光の尘3 分钟前
C语言菜鸟入门·关键字·float以及double的用法
运维·服务器·c语言·开发语言·stm32·单片机·c
嵌入式大圣2 小时前
单片机结合OpenCV
单片机·嵌入式硬件·opencv
日晨难再3 小时前
嵌入式:STM32的启动(Startup)文件解析
stm32·单片机·嵌入式硬件
yufengxinpian4 小时前
集成了高性能ARM Cortex-M0+处理器的一款SimpleLink 2.4 GHz无线模块-RF-BM-2340B1
单片机·嵌入式硬件·音视频·智能硬件
网易独家音乐人Mike Zhou11 小时前
【卡尔曼滤波】数据预测Prediction观测器的理论推导及应用 C语言、Python实现(Kalman Filter)
c语言·python·单片机·物联网·算法·嵌入式·iot
zy张起灵11 小时前
48v72v-100v转12v 10A大功率转换电源方案CSM3100SK
经验分享·嵌入式硬件·硬件工程
lantiandianzi18 小时前
基于单片机的多功能跑步机控制系统
单片机·嵌入式硬件
哔哥哔特商务网18 小时前
高集成的MCU方案已成电机应用趋势?
单片机·嵌入式硬件
跟着杰哥学嵌入式18 小时前
单片机进阶硬件部分_day2_项目实践
单片机·嵌入式硬件