当前位置: 首页 > article >正文

历遍单片机下的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 为成功的状态
#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一下

#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() {

}

看看运行效果

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设备

#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() {
  // 循环代码(如果需要)
}
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 处有这个设备


http://www.kler.cn/a/405311.html

相关文章:

  • 第 24 章 -Golang 性能优化
  • 日常开发记录-正确的prop传参,reduce搭配promise的使用
  • 神经网络10-Temporal Fusion Transformer (TFT)
  • Flutter踩坑记录(三)-- 更改入口执行文件
  • pdf文档动态插入文字水印,45度角,旋转倾斜,位于文档中央,多行水印可插入中文
  • 影视后期学习Ⅰ~
  • 浅谈新能源光储充一体化电站设计方案
  • PyTorch图像预处理:计算均值和方差以实现标准化
  • 网安基础知识|IDS入侵检测系统|IPS入侵防御系统|堡垒机|VPN|EDR|CC防御|云安全-VDC/VPC|安全服务
  • RocketMQ文件刷盘机制深度解析与Java模拟实现
  • Leecode刷题C语言之统计不是特殊数字的数字数量
  • xbh的比赛
  • Qt 的事件投递机制:从基础到实战
  • 动态调试对安全研究有什么帮助?
  • 设计模式之 模板方法模式
  • vue中路由缓存
  • Python创建虚拟环境报错:Error: Command......
  • 项目中排查bug的思路案例
  • 【Spring MVC】关于Spring MVC编程中与http请求的参数传递的详细介绍
  • 【MySQL系列】深入理解MySQL中的存储、排序字符集
  • Ubuntu20.04从零安装IsaacSim/IsaacLab
  • python内存分析
  • Qt-常用的显示类控件
  • Zookeeper集群搭建Centos环境下
  • ROS机器视觉入门:从基础到人脸识别与目标检测
  • 网络安全中常用浏览器插件、拓展